React Native元素定位问题

在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优化掉。

参考链接:software-mansion/react-native-reanimated#3188

文章首发于http://blog.orangii.cn/2023/react-native-measure-view/,转载请注明出处。博客所有文章遵循CC BY-NC 4.0协议

评论

  1. Android Chrome
    6 月前
    2023-11-11 11:25:36

    只有膜拜大佬,另外就是评论提示框文字显示不全

    • 博主
      橙子CY
      Macintosh Chrome
      6 月前
      2023-11-13 10:40:31

      是手机嘛,我PC看起来是正常的

  2. Windows Edge
    7 月前
    2023-11-05 10:33:41

    只有膜拜大佬

    • 博主
      胖虎同学
      Windows Chrome
      7 月前
      2023-11-05 11:18:51

      其实是工作上踩坑了所以来记录下,感觉这种东西不好搜到

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
橙橙梓
甘城猫猫
颜文字
Emoji
小恐龙
花!
上一篇