React-Native APP兼容采坑记录

时间:2024-04-15 11:02:25
APP最近测试出一些兼容性问题,这里记录一下,以免重复踩坑
一、TextInputoppovivo等手机上无法弹出键盘

此乃react-native神坑之一,官方提供的组件竟然还存在兼容性问题,简直了,文本输入框弹不出键盘,用户还用个“锤子”。打住,继续聊bug

 

bug的详细表现为:

(1) 第一次进入界面可以正常弹出键盘,然后返回上一页,再进入当前页面,则有一定几率(50%左右)键盘无法弹出。

(2) 如果手机锁屏再打开,原先不能调起软键盘的界面就可以调起

(3) alter弹框之后,原先不能调起软键盘的界面也是可以调起

(4) 在用户进入页面的时候默认显示一个modal(啥叫modal?点击这里查看),大概0.5后关闭,之后再使用不会出现键盘无法弹出的情况(经过反复测试验证)。

(5) 封装的原生EditText组件在RN中使用,键盘可以正常使用(注:该方法没有验证,结论来自https://blog.****.net/zpswz/article/details/83028737)。

 

结合上面的几种情况来看,锁屏的用户体验不好,alert弹框的样式不好设置。目前的解决方式只有两种了:

(1) 弹出透明modal然后自动消失

(2) 封装EditTextRN调用

由于没有封装原生控件的经验,也不知原生和RN中数据如何传递,因此目前采用了第一种方式。

 

解决方案代码详解如下:

1. import React from \'react\';  

2. import {View, ScrollView, Modal} from \'react-native\';    

3. 

4. export default class InputTextOppoDemoPage extends React.Component {  

5.   

6.     constructor(props) {  

7.         super(props)  

8.         this.state = ({  

9.             //兼容oppo手机textinput组件的modal  

10.             isModalOppo: false  

11.         })  

12.     }  

13.   

14.     /** 

15.     *显示独占框--oppo   

16.     */  

17.     showModalOppo() {  

18.         this.setState({  

19.             isModalOppo: true  

20.         })  

21.     }  

22.   

23.     /** 

24.      * 关闭独占框--oppo 

25.      */  

26.     hideModalOppo() {  

27.         this.setState({  

28.             isModalOppo: false  

29.         })  

30.     }  

31.   

32.     /** 

33.      * android平台必须实现--oppo 

34.      */  

35.     onRequestCloseOppo() {  

36.         this.setState({  

37.             isModalOppo: false  

38.         });  

39.     }  

40.       

41.     /** 

42.      * 兼容oppo textinput组件 

43.      */  

44.     componentDidMount() {  

45.         //刚进入页面时显示modal,modal的样式被设置为透明,用户看不见  

46.         this.showModalOppo()  

47.         //0.5秒之后关闭modal  

48.         setTimeout(() => {  

49.             this.hideModalOppo()  

50.         }, 500)  

51.     }  

52.   

53.     /** 

54.      * 组件渲染 

55.      */  

56.     render() {  

57.   

58.         return (  

59.             <ScrollView style={{flex:1} keyboardShouldPersistTaps={\'handled\'}>  

60.                   

61.                 {/* 兼容oppo手机textinput */}  

62.                 <Modal  

63.                     animationType=\'fade\'            // 淡入淡出  

64.                     transparent={true}              // 透明  

65.                     visible={this.state.isModalOppo}    // 根据isModalOppo决定是否显示  

66.                     onRequestClose={() => { this.onRequestCloseOppo() }}  // android必须实现  

67.                 >  

68.                     {/* 设置modal颜色为透明 */}  

69.                     <View style={{ height: 100, width: 180, alignItems: \'center\', justifyContent: \'center\', backgroundColor: \'rgba(255, 255, 255, 0)\', borderRadius: 10 }}>  

70.                     </View>  

71.                 </Modal>  

72.   

73.             </ScrollView>  

74.         )  

75.     }  

76. }  

 

在所有包含TextInput的组件中引入上述代码即可解决TextInput键盘不弹出问题。不过,这种方式的不好之处就是比较麻烦。有TextInput组件的地方都要引入这一大段代码,有点冗余。这是目前我们能力下能提出的最好的解决办法了,有其他的办法可以评论交流。

 

再啰嗦一下我查证该bug遇到的一个有趣的情况:

 

(1) React-NativeGithub Issue里发现关于这个问题的描述:大致意思是反馈了oppo手机React-Native原生组件文本输入框TextInput不弹出键盘的问题

 

(2) React-NavigationGithub Issue里面也发现了一个类似的:大致意思是说,使用React-Navigation路由导致了在oppo手机TextInput键盘不弹出。 

 

(3) 同时之前还在oppo开发者社区官网上面看到了关于React-Native TextInput组件不弹键盘的反馈,地址已不可考。

 

综合以上三点可以看出,由于TextInput组件这个情况比较特殊,可能有三个方面的原因导致,就连笔者目前也不敢断定,不过很有可能是oppo手机兼容性的问题,如果您有更好的见解,欢迎评论交流。由于oppovivo、魅族等国产手机对Android定制加深,不可避免的产生了兼容性问题,这方面小米和华为做的就非常好。基本上没有不兼容问题。

 

可以看到,这个问题2017年就被发现了,到现在已经2年多过去了,仍然没有解决。给广大开发者造成了不小的麻烦,希望相关开发者不要踢皮球,尽快解决。

 

二、Android6.0以下相机权限问题

(1) 问题说明,该bug仅仅存在于react-native-camera 1.1.4版本,之后再更高版本的如1.13.0测试该问题已不存在。

(2) bug的主要情况是react-native-camera对于相Android6.0以下版本相机权限的控制问题,明明没有获取到相机权限,却返回已获取。导致相机不能正常工作。

 

针对该问题的解决方式是修改handlePermissions.js,具体见下图

 

三、ImageBackgroud组件不指定Source导致应用闪退问题

(1) 问题说明:该问题尚不确定是Android版本问题还是机型问题

出现错误导致闪退的是这样一段代码,该代码在小米Mix3Android9)上面显示没问题,就显示空白,在Oppo A53m (Android 5.1)上面就闪退。

 

1. <ImageBackground source={require(\'\')}  width = 100 height = 100/>  

 

(2) 解决说明:指定一个默认的空白图片即可

 

1. <ImageBackground source={require(\'../../../../assets/4/blank.jpg\')}  width = 100 height = 100/>