只是記錄一下自己遇到的些許問題和解決方案的彙總,方便以後查閱。
廢話不多說,直接上重點:(遇到的難題)
一、antd-design組件難以自定義樣式
這裏 antd-design 不像web一樣,可以直接找到樣式class在global中去定義。在antd-design裏有一個後門,就是styles屬性,一般我們要修改樣式,都可以去源碼裏找到對應component的style目錄,我們就可以找到對應的樣式對象,再複用就好。最多的要數List中的List.Item的樣式了。
需求裏要求這樣:
就像這裏的List裏我們不需要上下的border,那隻用在List里加上這一行就好。
<List styles={{Body: { borderTopWidth: 0 },
BodyBottomLine: { borderBottomWidth: 0, },
}}>{props.childen}</List>
那爲什麼是這幾個屬性呢?那這就是上面說的,要去源碼裏看了List的style 當然,其他屬性也可以自己查找。
今天發現了一個坑爹的樣式,< TextArea /> 文本域,RN裏沒有單獨的這樣的標籤,只是會把Input 添加一個多行的屬性。需求需要實現這樣的效果:
需求主要有:
- 沒有上下邊框
- 右下角有實時統計字數的功能
- 內容的padding樣式。
開始以爲和前面一樣可以在組件中找到對應的樣式屬性對象解決。然而,並沒有這麼簡單0.0。到了源碼裏,看到這些:(無語。)
只要思想不滑坡,方法總比困難多!
- 繼續設置邊框色值borderBottomColor爲文本域的背景色(’#fff’)或者背景色,這樣就看不出來了。
- 只能放棄該組件的count功能,自己另外用onChange()單獨實現了,只用自己控制下最大長度就好。
- 縱向的直接在組件的style樣式裏,用paddingVertical即可直接實現。
二、Toast問題
在項目中,我們要的toast圖案啊,樣式啊,位置啊,這些可能需要不一樣一些,但是antd-design裏卻好多都是定的,而且node裏還需要一個 < Provider /> 包一層。這樣就讓我在網絡交互上的一些集中處理上的錯誤提示這些就比較棘手,不知道這個Toast應怎麼掛載到 < Provider /> 上。所以,我找到了這個組件,react-native-root-tips ,還是很好用的(這裏掛上文檔鏈接)。
該組件可以在全局定義一些默認樣式,基本解決了當前的一些問題。但是還是有些難以滿足,那隻好本地化了。把node_modules裏的文件本地化,做一些定製化需求即可。
三、input自動跳轉
驗證碼上,要實現六個區塊,輸入後自己跳到下個區塊。同時支持任意區塊的回刪。
這裏就說下主要思路吧:
- 先遍歷出6個都設置好ref,
ref={r=>this.input[i]=r}
以便確定對應的input做出focus()狀態。還需要間提供onKeyPress() 方法,確定用戶按下的是回撤還是數字。onKeyPress=(e)=>{……… e.nativeEvent.key (爲按下的鍵值)}
- 還需要定一個valueList的數組,來存儲每個input裏的值。在onChangeText=(text)=>{…… 處理}
- 鍵盤我們需要加一個完成的類似按鈕的話,可以帶上這兩個屬性:
returnKeyType=‘done’
returnKeyLabel=‘完成’
ps:若“完成”兩字爲出現,可以試試改變模擬器的系統語言。
- 每個激活態的下邊框樣式不同,可以在state裏定義一個focusList來做判斷。
四、狀態欄
主題對於一些頁面,會對狀態欄的主題有要求。
這次需求裏,在 ’我的’ 頁面,要求狀態欄爲白色,其他則爲黑色。開始是在 ’我的’ 裏,執行
Status.setBarStyle(‘light-content’),
再在’我的’裏去其他頁面的入口,每個頁面都加一個
Status.setBarStyle(‘dark-content’)
這樣雖然可以實現需求,但是極不方便維護。也容易出錯。於是,我在react-navigation裏找到了這個,發現從navigation裏做一層攔截,將會相當有用。
export default () => (
<App
onNavigationStateChange={(prevState, currentState, action) => {
const currentRouteName = getActiveRouteName(currentState);
const previousRouteName = getActiveRouteName(prevState);
if (previousRouteName !== currentRouteName) {
//‘我的'頁面上的statusBar顏色主題爲’light-content‘
if (currentRouteName == 'My') {
StatusBar.setBarStyle('light-content');
} else {
StatusBar.setBarStyle('dark-content');
}
}
}}
/>)
這樣在最頂層的App.js中就可以進行統一管理了。
五、標籤欄
對於標籤欄,我們會有多個icon的狀態。所以,一般會有2N個對應的對應的icon。只用在createBottomTabNavigator()對每一項的
navigationOptions:{
tabBarIcon:({tintColor,focused})=>(
<Image style={…} source={focused? 激活態圖 : 未激活圖 } />
)
}
六、軟鍵盤問題
問題1:當鍵盤失焦,(點擊其他非輸入區域時,要取消鍵盤)有兩個思路:
- (推薦)直接調用 Keyboard.dismiss( ) 方法,來取消鍵盤。這裏我們在最頂層裏設置onPress() 即可實現功能,但是,該組件點擊會有一定的透明樣式,可以手動設置
activeOpacity={1}
讓其不實現透明功能。ps:也可用.
- 對input取ref,也是在最頂層的組件設置onPress( ),將ref設置。ex. this.input.blur( )
問題2:點擊input,鍵盤會出現遮擋的情況,期望input可以跟鍵盤上浮。先設置以下
鍵盤監聽:
// 監聽鍵盤彈出與收回
componentDidMount() {
this.keyboardWillShowListener = Keyboard.addListener(
'keyboardWillShow',
this.keyboardDidShow,
);
this.keyboardWillHideListener = Keyboard.addListener(
'keyboardWillHide',
this.keyboardDidHide,
);
}
//註銷監聽
componentWillUnmount() {
this.keyboardWillShowListener && this.keyboardWillShowListener.remove();
this.keyboardWillHideListener && this.keyboardWillHideListener.remove();
}
//鍵盤彈起後執行
keyboardDidShow = () => {
// this_scrollView.setContentOffset({x: 0, y: -300, animated: true});
};
//鍵盤收起後執行
keyboardDidHide = () => {
this.setState({ scrollOffsetY: 0 })
}
在input的onfocus( )裏,要設置一個高度,400比鍵盤高度高一些。對菜單列表scroll滾動到指定區域。這個具體看需求:
this.setState({ scrollOffsetY: 400 }, () => {
setTimeout(() => {
this._scrollView.scrollTo({ x: 0, y: index >= 2 ? (index - 1) * 50 : 0, animated: true });
}, 100)
})
以上,爲我現階段整理的部分,以後還會持續更新。若有更好的解決方式或意見,歡迎一起探討。O(∩_∩)O哈哈~