React Native 元素布局属性

1,968 阅读2分钟

这是我参与8月更文挑战的第20天,活动详情查看: 8月更文挑战

前言

“八月的色彩是用金子铸就的,明亮而珍贵;八月的色彩是用阳光酿造的,芬芳而灿烂。”

未来的日子,愿你把自己调至最佳状态,缓缓努力,慢慢变好 Y(^o^)Y。

React-Native 中可能会遇到需要动态计算某个元素的宽高和位置信息

回想一下,我在开发中是否遇到过下面的场景:

  1. 动态获取父元素的宽高
  2. 动态获取点击元素的位置,从而计算某个元素的位置
  3. 动态获取点击元素的宽高
  4. 等等

要想解决上面场景中,我们肯定需要获取元素的布局,所有首先我们要先了解一下它的布局事件对象。

LayoutEvent

React Native 提供了布局事件对象LayoutEvent),组件的生成或者布局发生变化后,会作为onLayout回调函数的参数返回。

LayoutEvent object is returned in the callback as a result of component layout change, for example onLayout in View component.

例如:

{
    layout: {
        width: 375,
        height: 50,
        x: 0,
        y: 42.5
    },
    target: 1127
}

属性与值

  • height number 类型。 布局改变后组件的高度。
  • width number 类型。 布局改变后组件的宽度。
  • x number 类型。 在父组件内的组件X坐标。
  • y number 类型。 在父组件内的组件Y坐标。
  • target numbernull或者 undefined 类型 接收PressEvent的元素的节点id

引用LayoutEvent属性的组件

  • Image
  • Pressable
  • ScrollView
  • Text
  • TextInput
  • TouchableWithoutFeedback
  • View

组件在加载时或者布局变化以后调用 onLayout({nativeEvent: {layout: {x, y, width, height}}})

onLayout() 直接获取布局

在支持onLayout()的元素中,直接使用:

const onLayout = ({
    nativeEvent: {
      layout: { x, y, width, height },
    },
  }) => {
    console.log(x, y, width, height);
    // todo
    // 获取到布局属性后,就可以直接使用了
  };

...
return(
  <View onLayout={onLayout} style={{ width: '100%' }}>
    <Text>onLayout()测试</Text>
  </View>
)

使用 DOM 节点的 measure() 方法

获取DOM节点的ref属性,然后直接使用 measure() 方法

// 定义一个ref
const refView = useRef(null);

useEffect(() => {
  refView?.current.measure((x, y, width, height, pageX, pageY) => {
    console.log(x,y,width,height,pageX, pageY)
    // todo
  })
}, []);

...
return(
  <View ref={refView} style={{ width: '100%' }}>
    <Text>onLayout()测试</Text>
  </View>
)

onLayout() 和 measure() 获取的位置属性 x, y 是相对于当前元素的父元素来说的。

使用原生的 UIManager measure方法

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

const refView = useRef(null);

const handleClick = () => {
  UIManager.measure(findNodeHandle(refView),
    (x,y,width,height,pageX,  pageY)=>{
		  // todo
    });
}

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。

文章如有错误之处,希望在评论区指正🙏🙏。