只是记录一下自己遇到的些许问题和解决方案的汇总,方便以后查阅。
废话不多说,直接上重点:(遇到的难题)
一、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哈哈~