1.ScrollView的高度問題,在使用ScrollView時,一般不直接設(shè)置高度,而是設(shè)置{flex: 1},以使其自動填充父容器的空余空間,這個時候父容器也要設(shè)置了{flex: 1}或者指定了高度。
2.在引用ScrollView并調(diào)用scrollTo方法時,有些時候Android上并不執(zhí)行scrollTo方法,特別是在視圖剛渲染的時候,更容易出現(xiàn)這個問題,是因為Android系統(tǒng)組件生命周期的原因,遇到這種情況,可以對scrollTo做下延遲處理,雖然iOS一般不會出現(xiàn)這個問題,但是延遲一下也沒啥大問題,另外由于做了延遲處理,可能會出現(xiàn)在ScrollView調(diào)用scrollTo方法時,ScrollView的引用已經(jīng)被釋放了,或者說組件已經(jīng)unAmount了,這時候會出現(xiàn)問題,為避免這種問題,調(diào)用scrollTo前最好判斷下ScrollView是否還在,例如:
setTimeout(() => {
if (this._scrollView) {
this._scrollView.scrollTo({x: 0, y: 0});
}
}, 200);
3.ScrollView里的可點擊組件,如TouchableOpacity在ScrollView滑動結(jié)束時點擊沒反應(yīng)的問題,這個是ScrollView自身原因?qū)е碌?,在ScrollView滑動時,通常會自動屏蔽點擊事件,這就可能會給用戶造成ScrollView滑動結(jié)束了但是點擊TouchableOpacity沒反應(yīng)的問題或需要點擊兩次才觸發(fā)事件的情況,這個時候可以嘗試給ScrollView添加如下屬性:
keyboardShouldPersistTaps="always"
但是在頁面刷新的時候還是會偶現(xiàn)點擊沒反應(yīng)的情況,不過是很少遇到了,目前沒發(fā)現(xiàn)完美的解決辦法,誰知道了也可以告訴我。
4.在ScrollView、FlatList或ListView高度發(fā)生變化時,且子組件內(nèi)容變動時,如果出現(xiàn)空白問題,可以通過設(shè)置removeClippedSubviews={false}屬性來解決。
5.ListView及類似組件,如果出現(xiàn)數(shù)據(jù)源中元素變了但是列表沒有刷新問題,多半是深拷貝、淺拷貝的問題,比如數(shù)據(jù)源是個array,array里存放的是很多object,在某個事件觸發(fā)后array里的某個對象的某個值變了,這種情況下即便你SetState了但是ListView是不會重新刷的,因為數(shù)據(jù)源的地址沒變,所以列表頁不會重新渲染,解決這個有很多辦法,下面說其中一種
componentWillReceiveProps(props) {
let tempList = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.setState({
list: tempList.cloneWithRows(props.dataSource),
});
}
這個就是重新創(chuàng)建了一個數(shù)據(jù)源。還有一種就是對數(shù)組及數(shù)組中的對象進行深拷貝,當(dāng)然方法很多,能達到目的就行。
6.iPhone 6s Plus 0.5像素高度的分割線bug,跟iOS原生開發(fā)一樣,分割線的寬度或高度不能直接設(shè)置0.5,需要通過下面的方法來實現(xiàn):
/**
* @param size
* @returns {number}
*/
pixelRatioSize(size) {
return size * (2 / PixelRatio.get());
},
PixelRatio是react-native里的庫,用的時候?qū)С鰜砭托小?/p>
7.繪制帶邊框或者帶背景文字時,為了自適應(yīng)文字的寬度,可用下面的方法來實現(xiàn)
<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'}不可少,否則不能自適應(yīng)寬度。
8.在封裝公共組件時,比如封裝一個帶頭部標(biāo)題、描述、箭頭、底部描述或查看更多的可復(fù)用列表時,列表還需要外面?zhèn)魅胍粋€cell模板組件,這個cell模板組件是未知的,但是要在可復(fù)用列表中獲取這個cell模板的某些屬性,比如說高度,我們可以在cell里寫一個靜態(tài)方法,比如:
static getHeight(data) {
let rowHeight = 70;
if (data.tags && data.tags.length > 0) {
rowHeight = 90;
}
return rowHeight;
}
在封裝的列表組件調(diào)用這個方法:
_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組件的高度,我當(dāng)時是做三端適配時,適配web時需要計算高度。上面的static方法,有點類似于iOS里的類方法的概念,這個static不可缺少,否則hasOwnProperty會找不到這個方法。
9.陰影問題,iOS的陰影,可以通過設(shè)置style的方式來實現(xiàn),也可以通過圖片方式來實現(xiàn),Android的陰影,目前沒法通過設(shè)置style來實現(xiàn),只能依靠圖片方式,
由于Android系統(tǒng)的原因,超出視圖的內(nèi)容會默認被裁剪掉,所以在做iOS與Android兼容的時候要特別注意這點,另外假如iOS和Android統(tǒng)一使用切圖方式來實現(xiàn)陰影的話,如果考慮到資源包大小的話只使用一張通用的圖而不是多個機型適用的圖的話,圖片會有拉伸或者壓縮的問題,陰影效果看起來比較差,設(shè)置resizeMode也沒太多的改善,我試驗了另外一種方式,效果還算不錯,對Image的style里添加下面的樣式
transform: [{scaleX: (deviceWidth - 16) / (375 - 16)}],
scaleX后面的值換成Image的比例,這樣展示的陰影效果在各個手機機型上不會有太大的出入,是個不錯的選擇,當(dāng)然此方法僅適用于iOS或Android手機上,不適用于iPad屏幕,你可以對于Pad做特殊適配。
以上,后面遇到問題繼續(xù)記錄。