React Native에서 뷰 크기 가져 오기


147

특정보기의 크기 (너비와 높이)를 얻을 수 있습니까? 예를 들어 진행 상황을 보여주는 뷰가 있습니다.

<View ref='progressBar' style={{backgroundColor:'red',flex:this.state.progress}} /> 

다른 뷰를 올바르게 정렬하려면 뷰의 실제 너비를 알아야합니다. 이게 가능해?

답변:


315

React Native 0.4.2부터 View 구성 요소에는 onLayoutprop가 있습니다. 이벤트 객체를받는 함수를 전달하십시오. 이벤트 nativeEvent에는보기의 레이아웃이 포함됩니다.

<View onLayout={(event) => {
  var {x, y, width, height} = event.nativeEvent.layout;
}} />

onLayout뷰의 크기가 변경 될 때마다 핸들러는 호출됩니다.

주된주의 사항은 onLayout구성 요소가 마운트 된 후 핸들러가 먼저 한 프레임에서 호출되므로 레이아웃을 계산할 때까지 UI를 숨길 수 있습니다.


2
이 방법의 문제는 장치 회전 /보기 크기 변경시 onLayout이 다시 호출되지 않습니다.
Matthew

4
onLayout은 뷰의 프레임이 변경 될 때 호출됩니다. 아마도 뷰가 회전시 크기 나 위치를 변경하지 않을 수도 있습니다. 회전시 onLayout이 호출되는 UIExplorer의 onLayout 예제를보십시오.
ide

2
View치수에 따라 다르게 표시하고 싶다고 가정 해 봅시다 . 뷰 onLayout기능을 사용하여 뷰 표시 방법을 변경하는 방법을 이해하지 못합니다 . 그것이 무한 루프로 이어지지 않습니까?
Lane Rettig

2
@LaneRettig 그렇습니다. 이것이 실제로하고 싶은 일이라면 정적 평형에 도달하는 방식으로 코드를 작성해야합니다. 그러나 화면 크기에 따라보기를 사용자 정의하려는 경우 onLayout와 관련이 있습니다.
ide

7
@ide 레이아웃이 계산 될 때까지 UI를 어떻게 숨기겠습니까?
Irfanlone

27

이것이 나를 위해 일한 유일한 것입니다.

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

export default class Comp extends Component {

  find_dimesions(layout){
    const {x, y, width, height} = layout;
    console.warn(x);
    console.warn(y);
    console.warn(width);
    console.warn(height);
  }
  render() {
    return (
      <View onLayout={(event) => { this.find_dimesions(event.nativeEvent.layout) }} style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.android.js
        </Text>
        <Text style={styles.instructions}>
          Double tap R on your keyboard to reload,{'\n'}
          Shake or press menu button for dev menu
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('Comp', () => Comp);

14

기본적으로 크기를 설정하고 변경하려면 레이아웃에서 다음과 같이 상태로 설정하십시오.

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

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'yellow',
  },
  View1: {
    flex: 2,
    margin: 10,
    backgroundColor: 'red',
    elevation: 1,
  },
  View2: {
    position: 'absolute',
    backgroundColor: 'orange',
    zIndex: 3,
    elevation: 3,
  },
  View3: {
    flex: 3,
    backgroundColor: 'green',
    elevation: 2,
  },
  Text: {
    fontSize: 25,
    margin: 20,
    color: 'white',
  },
});

class Example extends Component {

  constructor(props) {
    super(props);

    this.state = {
      view2LayoutProps: {
        left: 0,
        top: 0,
        width: 50,
        height: 50,
      }
    };
  }

  onLayout(event) {
    const {x, y, height, width} = event.nativeEvent.layout;
    const newHeight = this.state.view2LayoutProps.height + 1;
    const newLayout = {
        height: newHeight ,
        width: width,
        left: x,
        top: y,
      };

    this.setState({ view2LayoutProps: newLayout });
  }

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.View1}>
          <Text>{this.state.view2LayoutProps.height}</Text>
        </View>
        <View onLayout={(event) => this.onLayout(event)} 
              style={[styles.View2, this.state.view2LayoutProps]} />
        <View style={styles.View3} />
      </View>
    );
  }

}


AppRegistry.registerComponent(Example);

래퍼로 다른보기가있는 다른 구성 요소에서이를 사용하여 수정 방법을 훨씬 더 변형시킬 수 있으며 onResponderRelease 콜백을 만들어 터치 이벤트 위치를 상태로 전달한 다음 자식 구성 요소로 전달할 수 있습니다. 속성으로 설정하면 onLayout 업데이트 상태를 재정의 할 수 있습니다 {[styles.View2, this.state.view2LayoutProps, this.props.touchEventTopLeft]}.


11

Dimensions모듈을 직접 사용하고 뷰 크기를 계산할 수 있습니다. 실제로, Dimensions기본 창 크기를 제공하십시오.

import { Dimensions } from 'Dimensions';

Dimensions.get('window').height;
Dimensions.get('window').width;

당신을 도울 수 있도록 노력하겠습니다!

업데이트 : 오늘 기본 StyleSheet사용 Flex 하여 뷰를 정렬하면 뷰 크기를 계산하는 대신 넓은 경우 우아한 레이아웃 솔루션으로 깨끗한 코드를 작성할 수 있습니다 ...

기본 창 크기 조정 이벤트에 응답 하는 사용자 지정 그리드 구성 요소를 작성 하더라도 간단한 위젯 구성 요소에서 좋은 솔루션을 생성 할 수 있습니다.


3
가, 왜 더 명확하게 문서화되지 않습니까!?! ( 'window'). width 등 대신 'width'와 'height'를 시도했습니다.

272
당신이 제공 한 예제 는 주어진 뷰가 아니라 창의 크기를 제공합니다 ; 이것은 어떻게 관련이 있습니까?
Mark Amery 16:25에서

1
@MarkAmery 창 크기를 사용하면 뷰 모양을 계획 할 수 있습니다.
Bruno Guerra

2
@BrunoGuerra 치수별로 특정보기 (창이 아닌) 크기를 얻는 코드를 보여 줄 수 있습니까?
Spark.Bao

4
장치를 회전 할 때 많은 장치에서 치수가 업데이트되지 않습니다. 이것은 알려진 문제 이며 반응 네이티브 0.32.0-rc.0에서 수정되지 않은 것 같습니다.
Glenn Lawrence

10

아마도 당신은 사용할 수 있습니다 measure:

measureProgressBar() {
    this.refs.welcome.measure(this.logProgressBarLayout);
},

logProgressBarLayout(ox, oy, width, height, px, py) {
  console.log("ox: " + ox);
  console.log("oy: " + oy);
  console.log("width: " + width);
  console.log("height: " + height);
  console.log("px: " + px);
  console.log("py: " + py);
}

내 인생에서 나는 올바르게 사용하는 방법을 알 수 없습니다 NativeMethodsMixin. 내가 무엇을하든 measure항상 정의되지 않습니다. 어떤 포인터?
chandlervdw

2
NativeMethodsMixin이 기능 을 사용할 필요는 없습니다 . 일부 요소에서만 사용할 수 있습니다. 예를 들어 TouchableWithFeedback측정 기능이 있지만 일반 기능 Touchable은 없습니다. 사용하는 유형을 변경하고 View심판을 얻고 측정 요소가 사용 가능한지 확인하십시오. 나는 또한 이것에 걸려 넘어졌다.
n0rm

-3

나를 위해 크기를 사용하도록 설정하는 비율은 나를 위해 일한 것입니다. width:'100%'


-4

다음은 장치의 전체 뷰의 크기를 가져 오는 코드입니다.

var windowSize = Dimensions.get("window");

다음과 같이 사용하십시오.

width=windowSize.width,heigth=windowSize.width/0.565


괜찮지 만 질문에 대답하지 않습니다.
Moso Akinyemi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.