🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
一直以来,我们都在用原始的CSS属性来设置外边距、内边距和颜色。但是,最新的CSS规范中增加了弹性盒子的概念,非常利于我们对App的UI进行布局,虽然你可能还不太熟悉它。 React Native 使用了 css-layout 库,在这个库中实现了弹性盒子,而这种模型无论对iOS还是Android来说都很好理解。 更幸运的是,Facebook针对许多语言单独实现了这个项目,这就引申出了许多新颖的用法,比如[在SVG中应用弹性盒子布局](http://blog.scottlogic.com/2015/02/02/svg-layout-flexbox.html)(是的,这篇文章也是我写的,为此我不得不熬到深夜)。 在这个App中,采用了默认的垂直流式布局,即容器中的子元素按照从上到下的顺序进行布局。比如: ![](https://box.kancloud.cn/2015-10-27_562f20d280987.png) 这被称作主轴, 主轴可能是水平方向,也可能是垂直方向。 每个子元素的纵向位置由它们的边距(margin)、间距(padding)和高决定。容器的alignItems属性会被设置为居中(center),这决定了子元素在交叉轴上的位置。在本例里,将导致子元素水平居中对齐。 接下来我们添加一些文本输入框和按钮。打开SearchPage.js 在第二个 Text 元素后添加: ~~~ <View style={styles.flowRight}> <TextInput style={styles.searchInput} placeholder='Search via name or postcode'/> <TouchableHighlight style={styles.button} underlayColor='#99d9f4'> <Text style={styles.buttonText}>Go</Text> </TouchableHighlight> </View> <TouchableHighlight style={styles.button} underlayColor='#99d9f4'> <Text style={styles.buttonText}>Location</Text> </TouchableHighlight> ~~~ 这段代码添加了两个顶级的视图:一个文本输入框外加一个按钮,以及一个单独的按钮。它们所使用的样式待会我们再介绍。 接着,在styles中增加如下样式: ~~~ flowRight: { flexDirection: 'row', alignItems: 'center', alignSelf: 'stretch' }, buttonText: { fontSize: 18, color: 'white', alignSelf: 'center' }, button: { height: 36, flex: 1, flexDirection: 'row', backgroundColor: '#48BBEC', borderColor: '#48BBEC', borderWidth: 1, borderRadius: 8, marginBottom: 10, alignSelf: 'stretch', justifyContent: 'center' }, searchInput: { height: 36, padding: 4, marginRight: 5, flex: 4, fontSize: 18, borderWidth: 1, borderColor: '#48BBEC', borderRadius: 8, color: '#48BBEC' } ~~~ 不同样式属性间以逗号分隔,这样你在container选择器后必须以一个逗号结尾。 这些样式将被文本输入框和按钮所用。 回到模拟器,按下Cmd+R ,你将看到如下效果: ![](https://box.kancloud.cn/2015-10-27_562f20d291be0.png) Go按钮和其紧随的文本框在同一行,因此我们将它们用一个容器装在一起,同时容器的flexDirection: 样式属性设置为’row’ 。我们没有显式指定文本框和按钮的宽度,而是分别指定它们的flex样式属性为4和1。也就是说,它们的宽度在整个宽度(屏幕宽度)中所占的份额分别为4和1。 而且,视图中的两个按钮都不是真正的按钮。对于UIKit,按钮不过是可以点击的标签而已,因此React Native开发团队能够用JavaScript以一种简单的方式构建按钮:TouchableHighlight是一种React Native组件,当它被点击时,它的前景会变得透明,从而显示其隐藏在底部的背景色。 最后我们还要在视图中添加一张图片。这些图片可以在[此处](http://cdn2.raywenderlich.com/wp-content/uploads/2015/03/ReactNative-HouseImage.zip)下载。下载后解压缩zip文件。 在 Xcode 打开 Images.xcassets 文件,点击加号按钮,添加一个新的image set。然后将需要用到的图片拖到image set右边窗口对应的位置。 ![](https://box.kancloud.cn/2015-10-27_562f20d2a9c92.png) 要让这些图片显示,必须停止你的 React Native App并重新启动。 在location按钮对应的 TouchableHighlight 组件下加入: `<Image source={require('image!house')} style={styles.image}/>` 然后,为图片添加适当的样式定义,记得在上一个样式之后添加一个逗号结尾: ~~~ image: { width: 217, height: 138 } ~~~ 由于我们将图片添加到了Images.xcasset资源包中,我们需要用require(‘image!house’)语句获得图片在App包中的正确路径。在Xcode中,打开Images.xcassets ,你可以找到名为house的image set。 回到模拟器,按下Cmd+R 查看运行效果: ![](https://box.kancloud.cn/2015-10-27_562f20d2d09c0.png) > 注意: 如果图片没有显示,却看到一个““image!house” cannot be > found”的提示,则可以重启packager(在终端中输入npm start命令)。 到目前为止,我们的App看上去有模有样,但它还缺少很多实际的功能。接下来的任务就是为App增加一些状态,执行一些动作。