如何用 React Native 创建一个iOS APP?(二)

我们书接上文《如何用 React Native 创建一个iOS APP?》,继续来讲如何用 React Native 创建一个iOS APP。接下来,我们会涉及到很多控件。

1 AppRegistry.registerComponent(

上述是定义应用程序的入口点。这也是 JavaScript 代码开始执行的地方。
这是一个本地用户界面反应的基本结构。我们定义的每个视图将遵循相同的基本结构。
在本教程中,我们将创建一个既可以浏览书籍又能知道书籍介绍比如作者、标题或关于书籍的简介。你还可以通过检索书名或作者来查找你想要的书籍。下面我要介绍这个应用程序。我们将会使用谷歌图书 API的数据。


如何用 React Native 创建一个iOS APP?(二)
添加一个标签栏

该应用程序会有一个有两项的标签栏--- Featured 和 Search。我们将首先添加它。
虽然你拥有 index.ios.js 文件中所有的代码,这是不推荐的,因为它会随着应用程序的代码的增加而混乱。为了更好的管理,我们要在不同的文件中创建类别。
创建两个 JavaScript 文件在你项目的根目录(和 index.ios.js 文件在相同的位置)。为 Search.js 文件和 Featured.js 命名。打开 Featured.js 并添加以下代码。

'use strict';
 
var React = require('react-native');
 
var {
    StyleSheet,
    View,
    Text,
    Component
   } = React;
 
var styles = StyleSheet.create({
    description: {
        fontSize: 20,
        backgroundColor: 'white'
    },
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
});
 
class Featured extends Component {
    render() {
        return (
        <View style={styles.container}>
            <Text style={styles.description}>
              Featured Tab
            </Text>
        </View>
        );
    }
}
 
module.exports = Featured;

你应该熟悉以上那个代码;它非常类似于我们之前看到的代码。我们设置 Strict Mode,加载 react-native 模块,创建视图样式,渲染UI 和渲染输出()函数功能。最后一行代码输出 Featured 类从而使他更方便地被其他文件所用。请注意我们所说的 class 和 function有点不同于 index.ios.js。JavaScript 有不同的方式表示 class和 function。可以随意选择你喜欢的你风格。接下来的教材中,我们将使用上边所使用的风格。
通过样式表中的定义,我们可以看出基本的 CSS 属性。我们为视图中的文本和中心内容设置字体大小和背景颜色。但你可能不熟悉 flex:1样式。这是 flexbox,CSS 规范的最新附加功能。flex:1 使元素标记容器占用的空间在屏幕上不被兄弟元素占用,否则它只能通过占用足够的空间来适应它的内容。以后我们将更加重视 flex。了解更多的Flexbox 样式,你可以阅读本指南。
在 Search.js 添加以下程序。

'use strict';
 
var React = require('react-native');
 
var {
    StyleSheet,
    View,
    Text,
    Component
   } = React;
 
var styles = StyleSheet.create({
    description: {
        fontSize: 20,
        backgroundColor: 'white'
    },
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
});
 
class Search extends Component {
    render() {
        return (
        <View style={styles.container}>
            <Text style={styles.description}>
              Search Tab
            </Text>
        </View>
        );
    }
}
 
module.exports = Search;

上述程序除了文本组件中的文本都类似于 Featured.js 代码。
在 index.ios.js 中剪切所有并粘贴在下边。

'use strict';
 
var React = require('react-native');
var Featured = require('./Featured');
var Search = require('./Search');
 
var {
    AppRegistry,
    TabBarIOS,
    Component
   } = React;
 
class BookSearch extends Component {
 
    constructor(props) {
        super(props);
        this.state = {
            selectedTab: 'featured'
        };
    }
 
    render() {
        return (
            <TabBarIOS selectedTab={this.state.selectedTab}>
                <TabBarIOS.Item
                    selected={this.state.selectedTab === 'featured'}
                    icon={{uri:'featured'}}
                    onPress={() => {
                        this.setState({
                            selectedTab: 'featured'
                        });
                    }}>
                    <Featured/>
                </TabBarIOS.Item>
                <TabBarIOS.Item
                    selected={this.state.selectedTab === 'search'}
                    icon={{uri:'search'}}
                    onPress={() => {
                        this.setState({
                            selectedTab: 'search'
                        });
                    }}>
                    <Search/>
                </TabBarIOS.Item>
            </TabBarIOS>
        );
    }
}
 
AppRegistry.registerComponent('BookSearch', () => BookSearch);

这时我们需要从我们创建的文件中导出两个模块,并将他们分配给变量。在 class 内部,我们指定一个构造函数来为 class 设置一个状态。这时我们要用组件的状态函数。创建一个名为 selectedTab 的属性,并将其值设置为 featured。我们将使用 featured 来确定哪个选项卡应该是主动的。然后设置默认选项卡。

在渲染()函数中我们使用 TabBarIOS 组件创建一个标签栏。记得添加组件使用解构作业否则使用完全限定名称,例如:React.TabBarIOS。

我们创建两个标签栏项目。我们为每个项目设立选中状态并定义一个函数,当这个项目被选中时就会被命名。在 Featured 选项卡中,选择设置为 true,如果 selectTab 状态我们前边定义的值为 feature,组件 selectedTab 是否等同于「搜索」。无论哪个选项卡被设置为 true 都将是活动选项卡。我们为标签栏项目使用系统图标。
注意我们使用我们的自定义组件标签,就像任何其他组件,例如:因为我们需要相应的模块,并将其分配到一个变量,你可以使用变量引入组件文件。这导致在 render() 函数的代码组件的类包含就像是文件的一部分。顺便说一下,我为各自变量的类名使用相同名称的变量,但不一定要这样,你可以尽可能的使用你喜欢的任何名称。
当标签栏被选中后,onPress 组件的属性就会被回调函数定义。selectedTab 属性的函数集值最终确定活动选项卡。
打开模拟器并按 Command-R 重新加载应用程序,你就会看到如下显示。


如何用 React Native 创建一个iOS APP?(二)

添加 Navigation Bar

接下来,我们将向应用程序添加一个导航栏,给这个项目添加两个以上的文件。他们将是根视图导航堆栈的标签。为 BookList.js 和SearchBooks.js 文件命名。
在 BookList.js 应用程序中添加以下代码。

'use strict';
 
var React = require('react-native');
 
var {
    StyleSheet,
    View,
    Component
   } = React;
 
var styles = StyleSheet.create({
 
});
 
class BookList extends Component {
    render() {
        return (
            <View>
        </View>             
        );
    }
}
 
module.exports = BookList;

在 SearchBooks.js 应用程序中添加以下代码。

'use strict';
 
var React = require('react-native');
 
var {
    StyleSheet,
    View,
    Component
   } = React;
 
var styles = StyleSheet.create({
 
});
 
class SearchBooks extends Component {
    render() {
        return (
            <View>
        </View>             
        );
    }
}
 
module.exports = SearchBooks;

在两个文件中,我们已经创建了一个带有空白视图的模块然后输出模块。

修改 Featured.js 如图:

'use strict';
 
var React = require('react-native');
var BookList = require('./BookList');
 
var {
    StyleSheet,
    NavigatorIOS,
    Component
   } = React;
 
var styles = StyleSheet.create({
    container: {
        flex: 1
    }
});
 
class Featured extends Component {
    render() {
        return (
            <NavigatorIOS
                style={styles.container}
                initialRoute={{
            title: 'Featured Books',
            component: BookList
            }}/>            
        );
    }
}
 
module.exports = Featured;

下一个 Search,js 修改如下所示:

'use strict';
 
var React = require('react-native');
var SearchBooks = require('./SearchBooks');
 
var {
    StyleSheet,
    NavigatorIOS,
    Component
   } = React;
 
var styles = StyleSheet.create({
    container: {
        flex: 1
    }
});
 
class Search extends Component {
    render() {
        return (
            <NavigatorIOS
                style={styles.container}
                initialRoute={{
            title: 'Search Books',
            component: SearchBooks
        }}/>            
        );
    }
}
 
module.exports = Search;

就像在 Featured.js,上面创建了一个导航控制器,设置其最初的路线并为它设置标题。

重新加载应用程序,你会看到如下所示:

获取和显示数据

现在我们要读取数据了。首先我们要构建有假数据的视图,然后使用来自 API 的真数据。
在 BookList.js 文件的顶部添加如下与其他变量的声明。

var FAKE_BOOK_DATA = [
    {volumeInfo: {title: 'The Catcher in the Rye', authors: "J. D. Salinger", imageLinks: {thumbnail: 'http://books.google.com/books/content?id=PCDengEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api'}}}
];

修改解构任务直到显示包含多个组件时我们才能使用。

var {
    Image,
    StyleSheet,
    Text,
    View,
    Component,
   } = React;

添加以下模版:

var styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
        padding: 10
    },
    thumbnail: {
        width: 53,
        height: 81,
        marginRight: 10
    },
    rightContainer: {
        flex: 1
    },
    title: {
        fontSize: 20,
        marginBottom: 8
    },
    author: {
        color: '#656565'
    }
});

然后修改如图所示的 class:

class BookList extends Component {
    render() {
    var book = FAKE_BOOK_DATA[0];
        return (
            <View style={styles.container}>
                <Image source={{uri: book.volumeInfo.imageLinks.thumbnail}}
                            style={styles.thumbnail} />
                <View style={styles.rightContainer}>
                    <Text style={styles.title}>{book.volumeInfo.title}</Text>
                    <Text style={styles.author}>{book.volumeInfo.authors}</Text>
                </View>
            </View>
        );
    }
}

重新加载应用程序就会有如下显示:

如何用 React Native 创建一个iOS APP?(二)

在以上代码中,我们创建了一个类似于从 API 中调用的目标 JSON,我们通过这个目标为单独的一本书创建了属性和价值。在 class 文件中,我们使用假数据只为了得到第一个元素来填充我们的观点。我们使用图像组件把图像加载成视图。需要注意的是,我们要在样式表中设置它的宽度和高度。如果你不指定图像在样式表中的尺寸,它就不会出现在视图中。
我们指定一个 flexDirection 样式:“行”容器。这将使带有这种风格元素的孩子们的布局默认为水平而不是垂直。需要注意的是我们该如何包装组件内的其他组件。在上面有带有两个孩子的主要容器物----一个图像和一个视图。这个视图能显示两个属于自己的孩子----即两个文本组件。
首先是图像布局,然后视图(right Container)水平放置在它旁边。我们指定一个 flex 模版:1rightContainer。这使得视图占据了剩下的空间而不是图像。如果你想要看到 flex 样式的影响,那就添加以下 rightContainer。

backgroundColor: 'red'

重新加载应用程序,你就会看到 rightContainer 样式的组件占用的空间。它占据整个空间而不被其他兄弟姐妹所占有。它并不拉伸屏幕,因为外容器有一些填充并且图像有边缘设置权利。

如何用 React Native 创建一个iOS APP?(二)

从 rightContainer 删除 flex:1,重新加载应用程序。现在组件只占用足够的可以适应其内容的空间。

如果你为 flex:2 的缩略图和 rightContainer 设置一种风格,他们可能占据相同数量的空间,而且他们会有一个 2:2(或1:1)的宽度比。你可以指定任何值,所有可能的比例都会考虑在内。

如何用 React Native 创建一个iOS APP?(二)

你也可以尝试不同的比率得到你喜欢的样式。对于本教程,我们将从为rightContainer 添加一个红色的背景这一步继续深入。

未完待续

OneAPM Mobile Insight 以真实用户体验为度量标准进行 Crash 分析,监控网络请求及网络错误,提升用户留存。访问 OneAPM 官方网站感受更多应用性能优化体验,想阅读更多技术文章,请访问 OneAPM 官方技术博客

本文转自 OneAPM 官方博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容