1.zIndex
在Android上使用zIndex來控制組件的層級,會遇到元素不顯示的問題。
解決方案:
盡量改變組件的順序,而不用zIndex
盡量不要使用zIndex來控制組件的層級,默認情況下,使用position: 'absolute'
后,后面的元素會默認覆蓋在前面的元素之上。所以刪除zIndex,改變一下組件的順序就OK啦。
issues: https://github.com/facebook/react-native/issues/8968
2.borderStyle:'dashed'
目前,Android上,如果想要實現一條水平方向的虛線,一開始想到的肯定是:
border: {
borderColor: 'red',
borderWidth: 0,
borderBottomWidth: 1,
borderStyle: 'dashed'
}
但是實際上,這樣是不會生效的,目前Android還不支持某一邊設置虛線。
解決方案:
方案一:假設我們想要一個線寬為h的水平虛線,設置一個高度為h的view,里面給一個view
設置四邊都是dashed
的邊框,borderWidth
為h,高度為0,然后外層設置overflow: 'hidden'
但是,你會發現,不管你怎么overflow,都是沒用的,Android照樣會渲染出兩個邊框,看起來overflow也沒有起作用。
方案二:換一種思路,再弄一個view,高度為h,背景顏色設置成你想要的顏色,然后把下面的border覆蓋掉。
此外,也可以關注下這個issue: Border is invisible when using borderStyle='dashed' with borderBottom #7838
3.TouchableOpacity等可點擊組件,有時候點擊不觸發onPress
這個問題,如果你只是在代碼里面放了類似下面的代碼:
<TouchableOpacity
style={styles.btn}onPress={this.onPress.bind(this)}>
<Text>立即預定</Text>
</TouchableOpacity>
並且onPress回調里面,並沒有做太多的邏輯,或者導致重新渲染。
那么,你沒有必要懷疑是你代碼的問題。RN對部分國產手機那些自定義的手勢支持不好。
4.[style]Android上Text默認的字體顏色,不是black,不是black,不是black
如果在Android上面,不顯示地給Text添加color,那么顯示出來的字體顏色就是灰色。跟iOS的表現不一致;
解決方案:
方案一:給每個Text都設置color
不足:每次都設置color。比較繁瑣
方案二:寫一個自定義組件
比如MyText,這個Text設置顏色,每次使用
xxx 就默認為你設置的顏色了。
不足:多出來了一個新的組件,也比較繁瑣。
多出來了一個新的組件,也比較繁瑣。
方案三:設置默認props
在入口文件里面寫上默認的style,比如:
Text.defaultProps.sytle = { 'color': '#212121'}
5.[ListView] renderRow 使用 this.state.xxx 屬性,setState({xxx:'xxx'})的時候 ListView沒有重新渲染
解決方案 重新設置 ListView 的 dataSource
6.[console] console.log()打印出來的對象,值不是最准確的,可能會受后面執行代碼的影響。
7.[網絡請求] 安卓機型連代理,有時抓不到請求
RN-andriod 用的網絡模塊是okhttp。這個模塊有一個類似代理路由的功能。通過代理(比如charles)發送一個請求時,如果該請求timeout或者error了(比如abort),okhttp在下次發送請求時可能不走charles。導致請求發出去了,但是charles抓不到。
8.[ios模擬器] 配置localhost:port之后,請求不到js
如果沒有提示說服務沒有啟動,提示404。基本上就是你電腦上沒有配置localhost對應的host。可能有寫hosts工具切換的時候,把localhost弄掉了。自己加回來:
127.0.0.1 localhost
9.RN0.46以上版本,使用touchable視圖包裹TextInput組件,touchable視圖上的onPress事件不能觸發
<TouchableOpacity>
<TextInput /> <---- touch not working here
<Text>Text</Text> <---- touch working here
</TouchableOpacity>
這個屬於官方未修復的問題,詳見https://github.com/facebook/react-native/issues/14958
臨時解決方案
把TextInput
包裹在一個View
中,給這個視圖的pointEvents
的屬性設置為none
。
<TouchableOpacity
onPress={()=>{console.log('press')}}>
<View pointerEvents='none'>
<TextInput editable={false} />
</View>
</TouchableOpacity>
10.TextInput
問題
TextInput
在安卓上默認有一個底邊框,同時會有一些padding
。如果要想使其看起來和iOS上盡量一致,則需要設置padding: 0
,同時設置underlineColorAndroid="transparent"
來去掉底邊框。
11.內容對齊問題
新增的展示內容與原有的結構往往不同,上下對齊需要通過margin和padding來調整。以下是調整中遇到的問題及解決:
1.ios和adr的表現不一致,測試時需要兩種機型都看下,在style中根據platform分別調整數值。
2.開發完后可能肉眼看覺得ok,但ui那邊是通過畫線驗收,如上圖所示。所以我們最好完了也用線對齊看看,減少修改的次數。
3.一行文字中同時存在漢字、數字、特殊符號時,它們有時不會底對齊,又或者ui要求垂直居中。這個可以通過lineHeight和paddingTop來調整。
4.必要時會用到0點幾這種數值。
5.一行字里有文字有數字不對齊這種,也可以換個字體解決哈~ Helvetica Verdana Cochin 都可以。
12.RN中組件陰影解決方案
不知從什么時候開始,公司的UI偏愛給所有模塊加上陰影效果,對於IOS系統,RN支持通過style設置陰影,但是Android系統着實讓人頭痛,在實踐過程中先后使用過多種方法。
<View elevation={5} style={styles.container}>
<Text>Hello World !</Text>
</View>
- IOS陰影實現方案
RN在ios系統上支持一系列陰影的樣式屬性,但這些屬性在Andriod上不會生效。
container : {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.2
}
- Android陰影實現方案
(1)使用elevation
屬性
<View elevation={2} style={styles.container}>
<Text>Hello World !</Text>
</Vie
container : {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.2,
elevation: 2
}
這個屬性可以寫在樣式里也可以直接當做組件的屬性,使用這個屬性可以產生一定的陰影效果,但是陰影顏色、透明度等都不能定制,大多數情況下並不滿足UI的要求。
(2)使用Image組件做背景
<Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch">
<YourView />
</Image>
或者
<View>
<Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch" />
<YourView />
</View>
設置Image的樣式未絕對定位鋪滿容器,類似於下面的ImageBackground
,RN0.46.4加入了一個組件ImageBackground
,可以像上面類似的方式使用.源碼非常簡單,https://github.com/facebook/react-native/blob/master/Libraries/Image/ImageBackground.js
'use strict';
const Image = require('Image');
const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
const ensureComponentIsNative = require('ensureComponentIsNative');
import type {NativeMethodsMixinType} from 'ReactNativeTypes';
class ImageBackground extends React.Component {
setNativeProps(props: Object) {
// Work-around flow
const viewRef = this._viewRef;
if (viewRef) {
ensureComponentIsNative(viewRef);
viewRef.setNativeProps(props);
}
}
_viewRef: ?NativeMethodsMixinType = null;
_captureRef = ref => {
this._viewRef = ref;
};
render() {
const {children, style, imageStyle, imageRef, ...props} = this.props;
return (
<View style={style} ref={this._captureRef}>
<Image
{...props}
style={[
StyleSheet.absoluteFill,
{
// Temporary Workaround:
// Current (imperfect yet) implementation of <Image> overwrites width and height styles
// (which is not quite correct), and these styles conflict with explicitly set styles
// of <ImageBackground> and with our internal layout model here.
// So, we have to proxy/reapply these styles explicitly for actual <Image> component.
// This workaround should be removed after implementing proper support of
// intrinsic content size of the <Image>.
width: style.width,
height: style.height,
},
imageStyle,
]}
ref={imageRef}
/>
{children}
</View>
);
}
}
module.exports = ImageBackground;
類似這種使用圖片都陰影背景的方式,一般設置里面內容的背景色為透明色,在實踐過程中有時會出現背景圖片還未加載完成,但里面的內容已加載完成的情況,會出現背景的一個跳變。
<Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch">
<View style={[styles.bg,StyleSheet.absoluteFill]}></View>
<YourView/>
</Image>
目前我采用的方案是使用一個單獨的View
墊底,較好的解決了這個問題。但是圖片拉伸變形的問題估計沒有好的解決方案了。
(3).使用“點9圖(.9圖)”封裝一個Native組件
Android系統支持一個牛叉的東西叫“點9圖”,以前真沒聽過,估計原生開發知道這個東西,它有一個特點是拉伸后不會變形,包括圓角。關於點9圖的概念可以參考.9.PNG是啥?.關於如何原生封裝一個帶有點9圖背景的組件,我也不知道啊,這部分是原生開發實現的。參考React Native顯示點9圖片,也許有幫助,現在我們業務線都是使用這種方式,效果比較好。