React Native教程 中文版<二>布局 layout-css样式
样式React Native 不实现 CSS,而是依赖于 JavaScript 来为你的应用程序设置样式。这是一个有争议的决定,你可以阅读那些幻灯片,了解背后的基本原理。 声明样式在 React Native 中声明样式的方法如下: var styles = StyleSheet.create({
base: {
width: 38,height: '#222222',active: {
borderWidth: 2,borderColor: '#00ff00',});
所有的属性名称和值是工作在网络中的一个子集。对于布局来说,React Native实现了Flexbox。 使用样式所有的核心组件接受样式属性。 <Text style={styles.base} />
<View style={styles.background} />
它们也接受一系列的样式。 {[styles.base, styles.background]} />
行为与 this.state.active && styles.active]} />
最后,如果真的需要,您还可以在render中创建样式对象,但是这种做法非常不赞成。最后把它们放在数组定义中。 <View
style={[styles.base,{
width: this.state.width,height: this.state.width * this.state.aspectRatio
}]}
/>
样式传递 为了让一个 call site 定制你的子组件的样式,你可以通过样式传递。使用 var List = React.createClass({
propTypes: {
style: View.propTypes.style,elementStyle: View.propTypes.style,render: function() {
return (
<View style={this.props.style}>
{elements.map((element) =>
<View style={[styles.element,this.props.elementStyle]} />
)}
</View>
);
}
});
// ... in another file ...
<List style={styles.list} elementStyle={styles.listElement} />
属性支持你可以在以下的链接中检测最新的 CSS 属性支持。
宽度单位和像素密度 react的宽度不支持百分比,设置宽度时不需要带单位 不知道是官网文档不全还是我眼瞎,反正是没找到,那做一个实验自己找吧: var Dimensions = require('Dimensions');
<Text style={styles.welcome}> window.width={Dimensions.get('window').width + 'n'} window.height={Dimensions.get('window').height + 'n'} pxielRatio={PixelRatio.get()} </Text>
默认用的是ihone6的模拟器结果是: window.width=375
window.height=667
我们知道iphone系列的尺寸如下图:
可以看到iphone 6的宽度为 375pt,对应了上边的375,由此可见react的单位为pt。 那如何获取实际的像素尺寸呢? 这对图片的高清化很重要,如果我的图片大小为100*100 px. 设置宽度为100 * 100. 那在iphone上的尺寸就是模糊的。 这个时候需要的图像大小应该是 100 * pixelRatio的大小 。 react 提供了PixelRatio 的获取方式https://facebook.github.io/react-native/docs/pixelratio.html var image = getImage({
width: 200 * PixelRatio.get(),height: 100 * PixelRatio.get()
});
<Image source={image} {{width: 200,height: 100}} />
flex的布局默认宽度我们知道一个div如果不设置宽度,默认的会占用100%的宽度, 为了验证100%这个问题, 做三个实验
<{[styles.text, styles.header]}>
根节点上放一个元素,不设置宽度
</Text>
<View {{height: 20,0)">backgroundColor: '#333333'}} />
<styles.header]}>
固定宽度的元素上放一个View,不设置宽度
</Text>
<100}}>
<333333'}} />
</View>
<styles.header]}>
flex的元素上放一个View,不设置宽度
</{{flexDirection: 'row'}}>
<{{flex: 1}}>
<333333'}} />
</View>
<1}}/>
</View>
结果可以看到flex的元素如果不设置宽度, 都会百分之百的占满父容器。 水平垂直居中 css 里边经常会做的事情是去讲一个文本或者图片水平垂直居中,如果使用过css 的flexbox当然知道使用 styles.header]}>
水平居中
</Text>
<100,0)">333333',0)">alignItems: 'center'}}>
<{{backgroundColor: '#fefefe',0)">width: 30,0)">borderRadius: 15}}/>
</View>
<styles.header]}>
垂直居中
</Text>
<justifyContent: 'View>
<styles.header]}>
水平垂直居中
</center',sans-serif; font-size:14px; line-height:22.3999996185303px">
打印出来的是 contain,cover,stretch 这几种模式, (官方文档不知道为什么不直接给出) 尝试使用这些mode<Text style={styles.welcome}> 100px height </Text> <Image style={{height: 100}} source={{uri: 'http://gtms03.alicdn.com/tps/i3/TB1Kcs5GXXXXXbMXVXXutsrNFXX-608-370.png'}} />
100px 高度, 可以看到图片适应100高度和全屏宽度,背景居中适应未拉伸但是被截断也就是cover。 100px height with resizeMode contain </Text> <View style={[{flex: 1,backgroundColor: '#fe0000'}]}> <Image style={{flex: 1,height: 100,resizeMode: Image.resizeMode.contain}} source={{uri: 'http:/'}} /> </View>
with resizeMode cover < cover模式同100px高度模式
和css的标准不同的是, 元素容器不用设置 relative',0)">marginLeft: 50}]}> </View>
相对定位的可以看到很容易的配合margin做到了。 (我还担心不能配合margin,所以测试了一下:-:) padding和margin我们知道在css中区分inline元素和block元素,既然react-native实现了一个超级小的css subset。那我们就来实验一下padding和margin在inline和非inline元素上的padding和margin的使用情况。 **padding ** styles.header]}>
在正常的View上设置padding
</Text>
<{{padding: 333333'}}>
<fefefe'}]}> Text Element</Text>
</styles.header]}>
在文本元素上设置padding
</0,0)">fe0000',0)">30}]}>
text 元素上设置paddinga
</ 在View上设置padding很顺利,没有任何问题, 但是如果在inline元素上设置padding, 发现会出现上面的错误, paddingTop和paddingBottom都被挤成marginBottom了。 按理说,不应该对Text做padding处理, 但是确实有这样的问题存在,所以可以将这个问题mark一下。
也就是如果Text元素在Text里边,可以考虑为inline, 如果单独在View里边,那就是Block。 文本元素首先我们得考虑对于Text元素我们希望有哪些功能或者想验证哪些功能:
先看看文字有哪些支持的style属性/*==========TEXT================*/
Attributes.style = {
color string
containerBackgroundColor string
fontFamily string
fontSize number
fontStyle enum('normal','italic')
fontWeight enum("normal",152)">'bold',152)">'100',152)">'200',152)">'300',152)">'400',152)">'500',152)">'600',152)">'700',152)">'800',152)">'900')
lineHeight number
textAlign enum("auto",152)">'left',152)">'right',152)">'center')
writingDirection enum('ltr',152)">'rtl')
}
实验1, 2, 3styles.header]}>
文本元素
</10}}>
<{styles.baseText} numberOfLines={5}>
<{styles.titleText} onPress={this.onPressTitle}>
文本元素{'n'}
</Text>
<Text>
{'n'}In this example,the nested title and body text will inherit the fontFamily from styles.baseText,but the title provides its own additional styles. The title and body will stack on top of each other on account of the literal newlines,numberOfLines is Used to truncate the text with an elipsis after computing the text layout,including line wrapping,such that the total number of lines does not exceed this number.
</Text>
</View>
styles = {
baseText: {
fontFamily: 'Cochin',color: 'white'
},titleText: {
fontSize: 20,fontWeight: 'bold',}
}
从结果来看1,2,3得到验证。 但是不知道各位有没有发现问题, 为什么底部空出了这么多空间, 没有设置高度啊。 我去除 其实官方文档里边把 Text元素的子Text元素的具体实现是怎样的, 感觉这货会有很多bug, 看官文 {{fontWeight: 'bold'}}>
I am bold
<{{color: 'red'}}>
and red
</Text>
</Text>
"I am bold and red"
0-9: bold
9-17: bold,red
好吧, 那对于 Text的样式继承实际上React-native里边是没有样式继承这种说法的, 但是对于Text元素里边的Text元素,上面的例子可以看出存在继承。 那既然有继承,问题就来了! 到底是继承的最外层的Text的值呢,还是继承父亲Text的值呢? styles.header]}>
文本样式继承
</white'}}>
<red'}} {this.onPressTitle}>
文本元素{'n'}
<Text>我是white还是red呢?{'n'} </Text>
</Text>我应该是white的</ 结果可见是直接继承父亲Text的。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |