相对像素

  1. import {Dimensions} from 'react-native';
  2. /**
  3. * 相对像素
  4. * @param px 像素
  5. * @returns
  6. */
  7. export function mpx(px: number) {
  8. return (px * Dimensions.get('window').width) / 375;
  9. }

发送事件到 JavaScript

原生模块可以在没有被调用的情况下往 JavaScript 发送事件通知。最简单的办法就是通过RCTDeviceEventEmitter,这可以通过ReactContext来获得对应的引用,像这样
https://www.react-native.cn/docs/native-modules-android#%E5%8F%91%E9%80%81%E4%BA%8B%E4%BB%B6%E5%88%B0-javascript
https://www.react-native.cn/docs/native-modules-ios#%E7%BB%99-javascript-%E7%AB%AF%E5%8F%91%E9%80%81%E4%BA%8B%E4%BB%B6

跨组件通信

DeviceEventEmitter

https://blog.csdn.net/suwu150/article/details/81536432

import { DeviceEventEmitter } from 'react-native';
...
componentDidMount() {
    //收到监听
    this.listener = DeviceEventEmitter.addListener('通知名称', (message) => {
    //收到监听后想做的事情
    console.log(message);  //监听
    })
}
componentWillUnmount() {
    //移除监听
    if (this.listener) {
      this.listener.remove();
    }
  }
...



import { DeviceEventEmitter } from 'react-native';
...
startEmit() {
    //准备值,发监听
    const message = '监听';
    DeviceEventEmitter.emit('通知名称', message);
}
...

events.js模块

https://www.npmjs.com/package/events

// utils
const EventEmitter = require('events')
const ee = new EventEmitter()
export default ee

// components
import ee from './ee.js'
ee.on('message', function (text) {
  console.log(text)
})
ee.emit('message', 'hello world')

使用useReducer

useReducer

AppState,类似uniapp的onShow与onHide

  • active - 应用正在前台运行
  • background - 应用正在后台运行。用户可能面对以下几种情况:
    • 在别的应用中
    • 停留在桌面
    • 对 Android 来说还可能处在另一个Activity中(即便是由你的应用拉起的)
  • [iOS] inactive - 此状态表示应用正在前后台的切换过程中,或是处在系统的多任务视图,又或是处在来电状态中。

https://www.react-native.cn/docs/appstate

隐藏底部导航条

image.png
react-native-navigation-bar-color

隐藏顶部状态栏

最好不要改变hidden属性,在android低端机上会导致屏幕抖动
{isFullScreen && }

解决ScrollView与Touchable的手势冲突

https://stackoverflow.com/questions/33060859/react-native-touchable-is-disabling-scrollview

<TouchableWithoutFeedback onPress={...}>
  <View>
    <ScrollView>
      <View onStartShouldSetResponder={() => true}>
        // Scrollable content
      </View>
    </ScrollView>
  </View>
</TouchableWithoutFeedback>

alias

https://koprowski.it/import-alias-in-react-native-and-vscode/

native plugin ViewGroupManager和SimpleViewManager 区别

SimpleViewManager延伸View
ViewGroupManager延伸ViewGroup
所以为了简化事情,看起来每当你有一个非常相似的原生UI组件,那么你想要使用SimpleViewManager,但如果你想在父母中有孩子,那么你需要使用ViewGroupManager
https://www.thinbug.com/q/47830546#google_vignette
https://stackoverflow.com/questions/27352476/difference-between-view-and-viewgroup-in-android
image.png

native ui plugin加入children元素

core

// constructor
public TXSurfaceView(@NonNull Context context) {
    super(context);
    setupLayoutHack();
    // ... 
    // other code...
}

private void setupLayoutHack() {
    Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
        @Override
        public void doFrame(long frameTimeNanos) {
            manuallyLayoutChildren();
            getViewTreeObserver().dispatchOnGlobalLayout();
            Choreographer.getInstance().postFrameCallback(this);
        }
    });
}


// 设置覆盖元素的大小等
private void manuallyLayoutChildren() {
    for (int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        child.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
                      MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
        // 添加元素核心
        child.layout(0, 0, child.getMeasuredWidth() / 2, child.getMeasuredHeight() / 2);
    }
}