React-Native中一些常见的问题

1.Android Studio编译错误transformClassesWithJarMergingForDebug

原因:缓存或者内部原因。

解决方法:清空缓存或者参考:[(https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx/issues/2)

2.Android真机调试连接不上Chrome调试控制台

原因:手机所处的wifi环境与电脑不一致或者adb设置原因。

解决方法
——检查手机网络是否和电脑网络处于同一个ip,如未打开无线网络等原因。
——检查是否是8081端口被占用。
——如果项目跑的起来,但是调试控制台连接不上,并且报错是跨域问题,我们可以尝试修改adb环境配置,执行这一段代码:

adb reverse tcp:18081 tcp:18081

重新加载项目,并且修改控制台地址为http://localhost:8081/debugger-ui/查看是否有效。

3.ScrollView内部嵌套的ScrollView无法滚动

原因:JS中的ScrollView只是映射到常规的滚动视图android组件。Android默认不支持。如果你想使用它,你需要包装另一个能够这样做的android组件。

解决方案
参考:https://github.com/facebook/react-native/issues/2967

4.React-Native中的表单输入被键盘遮挡的问题

原因:默认我们可能需要解决的是在ios系统上的滚动,

解决方案
参考:https://blog.csdn.net/sinat_17775997/article/details/72953940

 ——插件解决 import KeyboardSpacer from 'react-native-keyboard-spacer'

Android推荐使用以下方法:

<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>

4.React-Native中的如何获取弹出的系统键盘的高度等信息

import { Keyboard } from 'react-native';
...
  componentWillUnmount() {
    this.keyboardDidShowListener.remove();
    this.keyboardDidHideListener.remove();
  }

  componentWillMount() {
    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
  }

  _keyboardDidShow(e) {

    /*
    endCoordinates: {
        screenX: 0, 
        height: 253, 
        width: 360, 
        screenY: 387
    }
    */

    this.setState({
      keyboardHeight: e.endCoordinates.height
    })

  }

  _keyboardDidHide(e) {
    this.setState({
      keyboardHeight: 0
    })
  }

5.React-Native中Android父元素内部子元素绝对定位超出父元素被隐藏

原因:此现象在ios能够正常的显示,在Android超出部分直接被隐藏,猜想应该就是Android的解析原因。

解决方案
这是我的一个hack解决办法,具体的情况我们先看下面这个栗子:

import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default class TestScreen extends Component {
    render() {
        return (
            <View style={styles.container}>
                <Text>我是测试页面</Text>
                <View style={styles.parent}>
                    <View style={styles.children}>
                        <Text>我是内部绝对定位文本</Text>
                    </View>
                </View>
            </View>
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex:1,
        alignItems: 'center',
        justifyContent: 'center',
    },
    parent: {
        width:300,
        height: 40,
        backgroundColor: 'yellow',
        alignItems:'center',
        position:'absolute',
    },
    children:{
        height:20,
        justifyContent: 'center',

        top:-10
    }
})

在Android上神奇的显示效果:

6.React-Native中如何设置像Web一样的backgroundImage?

原因:React-Native中并没有background-image属性,只有一个Image标签,我们可以将Image标签设置全屏或者父元素下全屏效果。

解决方案
参考:HOW TO SET A FULL-SCREEN BACKGROUND IMAGE IN REACT NATIVE

 <Image source={require('./assets/images/isolate/loginBg.png')} style={styles.backgroundImage} />

const styles = StyleSheet.create({
  backgroundImage:{
    flex:1,
    alignItems:'center',
    justifyContent:'center',
    width:null,    //不加这句,就是按照屏幕高度自适应 加上,就是按照屏幕自适应
    height:null,//不加这句,就是按照屏幕高度自适应 加上,就是按照屏幕自适应
    //resizeMode:Image.resizeMode.contain,
    backgroundColor:'rgba(0,0,0,0)', //祛除内部元素的白色背景 不写的话文本会有白色背景
  }
});

7.React-Native中如何获得ScrollView已经滚动的高度?

解决方案

...
_onScroll=(e)=>{
    console.log(event.nativeEvent.contentOffset.x);//水平滚动距离
    console.log(event.nativeEvent.contentOffset.y);//垂直滚动距离 
}
    <ScrollView onScroll={this._onScroll}>

    </ScrollView>
...

8.React-Native中如何设置阴影效果?

//ios

shadowColor:color, 
shadowOffset:  {width: number, height: number},
shadowOpacity:  number,
shadowRadius:  number 


//android

elevation:5

9.React-Native中如何获得组件在屏幕上的位置?

import { UIManager} from 'NativeModules';
import { findNodehandle } from 'react-native'
//如果不这样引入,可能会出现这个报错
//Undefined is not a function(React.findNodehandle)

//当某个组件onLayout的时候我们可以调用这个方法:

// x、y:为视图的相对位置。width、height:为视图的宽度和高度。pageX、pageY为视图在屏幕上的绝对位置

_onLayout = () => {
   const handle = findNodeHandle(this.innerScroll);
   UIManager.measure(handle, (x, y, width, height, pageX, pageY) => {
       console.log(x, y, width, height, pageX, pageY)
   });
}

10.React-Native中如何去适配iphoneX样式?


import {
    PixelRatio,
    Dimensions,
    Platform,
    findNodeHandle,
    UIManager
} from 'react-native';


export const deviceW = Dimensions.get('window').width;
export const deviceH = Dimensions.get('window').height;


// iPhoneX 适配问题   2018-4-4

const X_WIDTH = 375;
const X_HEIGHT = 812;

/**
 * 判断是否为iphoneX
 * @returns {boolean}
 */
export function isIphoneX() {
    return (
        Platform.OS === 'ios' &&
        ((deviceH === X_HEIGHT && deviceW === X_WIDTH) ||
            (deviceH === X_WIDTH && deviceW === X_HEIGHT))
    )
}

/**
 * 根据是否是iPhoneX返回不同的样式
 * @param iphoneXStyle
 * @param iosStyle
 * @param androidStyle
 * @returns {*}
 */

export function ifIphoneX(iphoneXStyle, iosStyle, androidStyle) {
    if (isIphoneX()) {
        return iphoneXStyle;
    } else if (Platform.OS === 'ios') {
        return iosStyle
    } else {
        if (androidStyle) return androidStyle;
        return iosStyle
    }
}

11.React-Native中自定义styleSheet?

import { StyleSheet, Platform } from 'react-native';

function create(styles) {
  const platformStyles = {};
  Object.keys(styles).forEach((name) => {
    const { ios, android, ...style } = styles[name];
    let xeStyle = style;
    if (ios && Platform.OS === 'ios') {
      xeStyle = { ...style, ...ios };
    }
    if (android && Platform.OS === 'android') {
      xeStyle = { ...style, ...android };
    }
    platformStyles[name] = xeStyle;
  });
  const result = StyleSheet.create(platformStyles);
  return result;
}

export default {
  ...StyleSheet,
  create,
};

//使用时:

import StyleSheet from '../utils/StyleSheet';
const styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'stretch',
    ios: {
      paddingTop: 64,
    },
    android: {
      paddingTop: 44,
    },
  },
});

12.React-Native中使用震动API

使用场景:新消息通知等场景。

  • Android注意事项:
    添加<uses-permission android:name="android.permission.VIBRATE"/>到AndroidManifest.xml.
  • 由于iOS中的振动持续时间不可配置,因此与Android有一些差异。在Android中,如果pattern是数字,则它指定以毫秒为单位的振动持续时间。如果pattern是一个阵列,那些奇数指数就是振动持续时间,而偶数指数则是分离时间。
  • 在iOS中,调用vibrate(duration)只会忽略持续时间并在固定时间内振动。虽然pattern阵列被用来定义每个振动之间的持续时间。
  • 也支持可重复的振动,振动将以定义的模式重复,直到cancel()被调用
import { Vibration } from 'react-native'

const DURATION = 10000
const PATTERN = [1000, 2000, 3000]

------------------------------------------------------------------------

Vibration.vibrate(DURATION)
// Android: 震动持续10秒
// iOS: 持续时间参数不生效,固定震动大约0.5秒

------------------------------------------------------------------------

Vibration.vibrate(PATTERN)
// Android: 等待1s -> 震动2s ->等待3s
// iOS: 等待1s -> 震动0.5秒 -> 等待2s -> 震动0.5秒 -> 等待3s -> 震动0.5秒

------------------------------------------------------------------------
//配置true参数将会无限震动,知道cancle方法的执行

Vibration.vibrate(PATTERN, true)
// Android: 等待1s -> 震动2s -> 等待3s -> 等待1s -> 震动2s -> 等待 3s -> ...
// iOS: 等待1s -> 震动0.5秒 -> 等待2s -> 震动0.5秒 -> 等待3s -> 震动0.5秒-> 等待1s -> 震动0.5秒 -> 等待2s -> 震动0.5秒 -> 等待3s -> 震动0.5秒 -> ...

------------------------------------------------------------------------

Vibration.cancel()
// Android: 停止震动
// iOS: 停止震动

这个版本未完善,持续更新汇总,欢迎留言分享经验。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值