首先,大概描述一下用到的框架:react-navigation(类似于ios中TabbarVC),Fetch(网络获取工具),Platform(平台判断-ios、安卓等),Dimensions(获取屏幕宽高-布局时常用到)等。下面会对这些框架或多或少的做一些讲解,主要是一些我遇到的问题的收集。
1.react-navigation
在移动开发中,我们常常需要设定每一个页面的标题和左右按钮,这个在原生开发中很容易的实现,对于一个接触RN不久的开发者来说还是有难度的,这个框架有一些弊病我前面的博客有提到,也有解决方案,这里不多做赘述。
a.标题设置(属性:title或headerTitle)
这里多说一句,react-navigation上导航栏的属性设置都是通过一个属性来的——navigationOptions,你只需要设置它就可以了,拿标题举例如下,其余的添加到属性里面就好。
static navigationOptions = ({ navigation, state }) => ({
// head导航栏
// title:<Text style={headerStyle.titlestyle}>我的标题</Text>,
headerTitle: '我的标题',
headerTitleStyle: { //标题样式,与headerTitle结合使用
alignSelf: 'center',
fontSize: 24,
lineHeight: 35
},
}
如上,标题的设置有两种方式,一种根据你的需要自定义,如上title(道理上来说可以为任意组件,未做验证),或者用第二种,自带默认的headerTitle,通过headerTieleStyle设置样式,这里主要说下在做适配的时候有些问题要注意:ios上的显示问题不大,但是如果适配安卓需要左右两边都添加按钮或者都不添加,这样子标题才会居中,只有一个的另一端可以添加一个<View/>做占位用。
b.设置左按钮(属性:headerLeft)
对于原生开发而言,这个是手到擒来的,样式设置也比较简单,但是RN好像并没有太多的可设定变更,可能跟要适配两端有关系吧,这里最好的设置就是重新定制左按钮,通过TouchableOpacity(RN中的点击事件)吧,如下
static navigationOptions = ({ navigation, state }) => ({
headerLeft: (
<TouchableOpacity onPress={() => {
navigation.goBack();
}>
<Image source={require('../../../../Resource/iosImg/left.png')} style={{ marginLeft: 5 }} //可以为任意显示组件
resizeMode="center"
/>
</TouchableOpacity>
),
}
这里注意一点,如果要隐藏导航栏直接设置header:null,但是必须重写navigationOptions属性的headerLeft方法,不然的话没办法调用goback或navigate等系列方法,亲测案例,希望大家不要在这绕太久。
c.设置右按钮(属性:headerRight)
在原生开发中,左右按钮的设定没有什么本质上的区别,但是RN中区别有点大,主要是在于你要执行的事件,左按钮一半情况下只需要返回上一级,它用到的事件对象navigation可以通过属性拿到,如上b点,但是右按钮可能会有其他事件,左按钮的其他事件同理,相对比较少就在一起说了,实现其他点击事件分3步走,如下:
(1)写法通b点,注意点击事件的写法,先判断navigation.state.params是否存在,存在就调用旗下子方法navigatePress,否则为null
headerRight: (
<TouchableOpacity style={{ top: 0, right: 0, height: 20, width: 35 }} onPress={navigation.state.params ? navigation.state.params.navigatePress : null}>
<Image source={require('../../../../../Resource/iosImg/more.png')} style={{ width: 20, height: 20 }} />
</TouchableOpacity>
)
(2)实现子方法
//右按钮相应事件
navigatePress = () => {
this.setState({
isshow: true //改变状态,渲染组件
})
}
(3)组件加载完成,重设props,定义子方法
componentDidMount() {
// 组件渲染之后重设props
this.props.navigation.setParams({
title: '自定义Header',
navigatePress: this.navigatePress
})
}
2.刷新界面
我用到的有两种,一个是setState()——异步刷新,宁外一个是this.forceUpdate()——同步刷新,亲身经历表示一定要结合使用,不然会有可能造成modal隐藏失败,换句话说就是,页面先跳转,但是异步的模态还没有执行,这样子会导致modal的显隐有问题,这种时候用this.forceUpdate()就可以避免这种情况。
3.适配安卓
对于初学者这是个比较棘手的问题,因为我是ios开发出家的,所以先是ios开发,然后安卓适配,其中一点前文已经提到,需要同时设置或不设左右按钮,标题才能居中,还有一点比较重要也是造成布局差异的元凶,就是TouchableOpacity组件,在ios中不论你设置组件的样式在TouchableOpacity或者其他内组件都可以正常显示,但是在安卓中TouchableOpacity的优先级好像要高点,如果你不在TouchableOpacity中设置样式就对出现一系列问题,所以建议在TouchableOpacity中设置精确样式,在内组件中只设置宽高即可,显示灵活多变,老铁们各自珍重。
4.约束ScrollView\FlatList\ListView(建议放弃,使用FlatList更简便,性能更好)
这些组件的高度好像不能通过自身的样式进行限定,所以我们需要借助外力,外层加一个<View></View>,设置view的高度即可,这样子便可以随意设定高度。
5.Modal(可以实现菊花效果)
RN中的弹窗图层,不能通过Alert点击事件改变其状态,亲测好想没什么用,就放弃了Alert组件,弹窗基本用modal完成,其方式简单,但是每个界面都用的话需要每个页面布局,所以还是比较烦的,用之前最好考虑好需要用到的弹窗(模态),设定好属性再开工。用法参考官方文档。
6.TextInput组件焦点问题
默认情况下,其焦点是在上下居中,靠左,大部分情况我们需要焦点停留在左上角初始状态,大概查了些资料,说到的很少,这里提一下,代码如下:
<TextInput
multiline={true}
textAlign='left' //初始焦点居左
textAlignVertical='top'//初始焦点靠顶部
placeholder="占位文字"
onChangeText={(text)=>this.setState{text}} //可以不用text,自己另外设定一个属性即可
placeholderTextColor='gray'
// editable={this.props.isEidt}
style={[styles.textStyle, { borderWidth: 0.5, borderColor: '#FAFAFA', top: this.props.top, }]} />
暂且至此,后记慢补。不喜忽喷,谢谢。