1.ScrollView的高度问题,在使用ScrollView时,一般不直接设置高度,而是设置{flex: 1}
,以使其自动填充父容器的空余空间,这个时候父容器也要设置了{flex: 1}
或者指定了高度。
2.在引用ScrollView并调用scrollTo
方法时,有些时候Android上并不执行scrollTo
方法,特别是在视图刚渲染的时候,更容易出现这个问题,是因为Android系统组件生命周期的原因,遇到这种情况,可以对scrollTo
做下延迟处理,虽然iOS一般不会出现这个问题,但是延迟一下也没啥大问题,另外由于做了延迟处理,可能会出现在ScrollView调用scrollTo
方法时,ScrollView的引用已经被释放了,或者说组件已经unAmount了,这时候会出现问题,为避免这种问题,调用scrollTo
前最好判断下ScrollView是否还在,例如:
setTimeout(() => {
if (this._scrollView) {
this._scrollView.scrollTo({x: 0, y: 0});
}
}, 200);
3.ScrollView里的可点击组件,如TouchableOpacity
在ScrollView滑动结束时点击没反应的问题,这个是ScrollView自身原因导致的,在ScrollView滑动时,通常会自动屏蔽点击事件,这就可能会给用户造成ScrollView滑动结束了但是点击TouchableOpacity
没反应的问题或需要点击两次才触发事件的情况,这个时候可以尝试给ScrollView添加如下属性:
keyboardShouldPersistTaps="always"
但是在页面刷新的时候还是会偶现点击没反应的情况,不过是很少遇到了,目前没发现完美的解决办法,谁知道了也可以告诉我。
4.在ScrollView、FlatList或ListView高度发生变化时,且子组件内容变动时,如果出现空白问题,可以通过设置removeClippedSubviews={false}
属性来解决。
5.ListView及类似组件,如果出现数据源中元素变了但是列表没有刷新问题,多半是深拷贝、浅拷贝的问题,比如数据源是个array,array里存放的是很多object,在某个事件触发后array里的某个对象的某个值变了,这种情况下即便你SetState了但是ListView是不会重新刷的,因为数据源的地址没变,所以列表页不会重新渲染,解决这个有很多办法,下面说其中一种
componentWillReceiveProps(props) {
let tempList = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.setState({
list: tempList.cloneWithRows(props.dataSource),
});
}
这个就是重新创建了一个数据源。还有一种就是对数组及数组中的对象进行深拷贝,当然方法很多,能达到目的就行。
6.iPhone 6s Plus 0.5像素高度的分割线bug,跟iOS原生开发一样,分割线的宽度或高度不能直接设置0.5,需要通过下面的方法来实现:
/**
* @param size
* @returns {number}
*/
pixelRatioSize(size) {
return size * (2 / PixelRatio.get());
},
PixelRatio
是react-native
里的库,用的时候导出来就行。
7.绘制带边框或者带背景文字时,为了自适应文字的宽度,可用下面的方法来实现
<View style={{marginTop: 3, flexDirection: 'row'}}>
<View style={{flexDirection: 'row',height: 15, alignItems: 'center', backgroundColor: '#FC3438'}}>
<Text style={[css.PingFangSCMedium, {
color: '#fff',
fontSize: 10,
marginHorizontal: 5,
marginVertical: 1.5,
}]} numberOfLines={1}
ellipsizeMode={'tail'}>{'文字长度不固定'}
</Text>
</View>
</View>
注:外层的View与View的style里的{flexDirection: 'row'}
不可少,否则不能自适应宽度。
8.在封装公共组件时,比如封装一个带头部标题、描述、箭头、底部描述或查看更多的可复用列表时,列表还需要外面传入一个cell模板组件,这个cell模板组件是未知的,但是要在可复用列表中获取这个cell模板的某些属性,比如说高度,我们可以在cell里写一个静态方法,比如:
static getHeight(data) {
let rowHeight = 70;
if (data.tags && data.tags.length > 0) {
rowHeight = 90;
}
return rowHeight;
}
在封装的列表组件调用这个方法:
_calculateTotalHeight = () => {
const {showHeader, dataSource, renderItem, separatorHeight, moreHeight, moreComponent} = this.props;
let height = 0;
if (!dataSource || dataSource.length === 0) return height;
if (showHeader) {
height = height + 50;//比如这里要加一个带title带描述的header
}
if (moreStr || moreComponent) {
height = height + moreHeight;//比如这里要加一个带底部更多的组件
}
let cellHeight = 0;
dataSource.map((item) => {
//renderItem类似于我上面说的cell模板组件
if (renderItem.hasOwnProperty('getHeight')) {
cellHeight = renderItem.getHeight(item);
}
height = height + cellHeight;
});
height = height + (dataSource.length - 1) * separatorHeight;
return height;
};
这只是一个例子,通常情况下我们不需要计算ListView组件的高度,我当时是做三端适配时,适配web时需要计算高度。上面的static方法,有点类似于iOS里的类方法的概念,这个static不可缺少,否则hasOwnProperty会找不到这个方法。
9.阴影问题,iOS的阴影,可以通过设置style的方式来实现,也可以通过图片方式来实现,Android的阴影,目前没法通过设置style来实现,只能依靠图片方式,
由于Android系统的原因,超出视图的内容会默认被裁剪掉,所以在做iOS与Android兼容的时候要特别注意这点,另外假如iOS和Android统一使用切图方式来实现阴影的话,如果考虑到资源包大小的话只使用一张通用的图而不是多个机型适用的图的话,图片会有拉伸或者压缩的问题,阴影效果看起来比较差,设置resizeMode
也没太多的改善,我试验了另外一种方式,效果还算不错,对Image
的style
里添加下面的样式
transform: [{scaleX: (deviceWidth - 16) / (375 - 16)}],
scaleX
后面的值换成Image
的比例,这样展示的阴影效果在各个手机机型上不会有太大的出入,是个不错的选择,当然此方法仅适用于iOS或Android手机上,不适用于iPad屏幕,你可以对于Pad做特殊适配。
以上,后面遇到问题继续记录。
网友评论