首页 小组 问答 话题 好文 素材 用户 唠叨 我的社区

[分享]React Native元素定位问题

鸟云Lv.1普通用户
2024-10-30 09:52:50
0
2

在Web上,获得一个元素的位置信息可以使用 getBoundingClientRect 方法获得,但是在RN的View上,就没有这样的方法了,需要使用RN View的专有方法:measure。

measure

measure的使用需要使用ref获取View(或其他原生RN容器,这里只能是原生RN的容器)引用,然后调用上面的measure方法,这个方法接受一个回调函数,参数分别为 x、y、width、height、pageX、pageY参数(参数按照顺序列举)。

但是如果元素实际未渲染(例如Flatlist中不在屏幕中没有渲染的元素),则无法获得它的位置。


import { useRef, FC } from 'react';
import { ScrollView, View, useWindowDimensions } from 'react-native';
 
export const TextComp: FC = (props) => {
  const viewRef = useRef<View>(null);
  const { width: windowHeight } = useWindowDimensions();
  const handleScroll = () => {
    viewRef.current?.measure?.((x, y, width, height, pageX, pageY) => {
      if (pageY < windowHeight) {
        console.log('View Appears');
        // ...
      }
    });
  }
  
  return (
    <ScrollView
      style={{ paddingVertical: 1000 }}
      handleScroll={handlesScroll}
      scrollEventThrottle={16}
    >
      <View ref={useRef}> ... </View>
    </ScrollView>
  );
}

可能遇到的问题

在安卓中,一个View如果只用来包含子元素,而不存在任何跟空间有关的属性(例如style、className、onLayout等),那么这个View会被安卓RN底层优化,从而导致这个View在Component Tree上并没有挂载。虽然不会影响页面视觉效果,但是会导致measure返回不可控的数值。

为了防止容器被优化,需要用到 collapsable 属性,例如下面的代码:


import { useRef, FC } from 'react';
import { ScrollView, View, useWindowDimensions } from 'react-native';
 
export const TextComp: FC = (props) => {
  const viewRef = useRef<View>(null);
  const { width: windowHeight } = useWindowDimensions();
  const handleScroll = () => {
    viewRef.current?.measure?.((x, y, width, height, pageX, pageY) => {
      if (pageY < windowHeight) {
        console.log('View Appears');
        // ...
      }
    });
  }
  
  return (
    <ScrollView
      style={{ paddingVertical: 1000 }}
      handleScroll={handlesScroll}
      scrollEventThrottle={16}
    >
      <View 
        ref={useRef}
        collapsable={false} // <---
      > ... </View>
    </ScrollView>
  );
}

 

除了上述方法外,使用Animated.View、为View添加style属性或者onLayout回调都会防止它被安卓RN优化掉。

鸟云
鸟云

2 小时前

签名 :   2       0
评论
站长交流