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、コンポーネントがマウントされてから1フレーム後にハンドラーが最初に呼び出されるため、レイアウトを計算するまでUIを非表示にすることです。


2
このアプローチの問題は、デバイスが回転したり、サイズが変更されたりすると、onLayoutが再度呼び出されないことです。
マシュー

4
onLayoutは、ビューのフレームが変更されたときに呼び出されます。おそらく、ビューはサイズや回転時の位置を変更しません。UIExplorerのonLayoutの例を見てください。onLayoutはローテーション時に呼び出されます。
2015年

2
View寸法によって表示を変えたいとしましょう。ビューのonLayout機能を使用してビューの表示方法を変更する方法がわかりません。それは無限ループにつながりませんか?
Lane Rettig、2016

2
@LaneRettigはい、そうです。これが本当にやりたいことである場合は、静的平衡に達するようにコードを記述する必要があります。しかし、画面の寸法に基づいてビューをカスタマイズしたいだけかもしれませんが、その場合onLayoutは無関係です。
2016

7
@ideレイアウトが計算されるまでUIをどのように非表示にしますか?
Irfanlone 2017

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コールバックを作成することで、変更方法のバリエーションをさらに作成できます。プロパティとして、配置{[styles.View2, this.state.view2LayoutProps, this.props.touchEventTopLeft]}などによってonLayout更新状態をオーバーライドできます。


11

Dimensionsモジュールを直接使用して、ビューのサイズを計算できます。実際、Dimensionsメインウィンドウのサイズを教えてください。

import { Dimensions } from 'Dimensions';

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

お役に立てれば幸いです。

更新:ビューを配置StyleSheetするFlexでネイティブを使用すると、ビューサイズを計算する代わりに、幅広いケースでエレガントなレイアウトソリューションを使用してクリーンなコードを記述できます...

メインウィンドウのサイズ変更イベントに応答するカスタムグリッドコンポーネントを構築すると、単純なウィジェットコンポーネントで優れたソリューションが生成される可能性があります


3
ああ、なぜこれがもっと明確に文書化されていないのですか!?!(「ウィンドウ」)の代わりに「幅」と「高さ」を

272
あなたが与えた例は、与えられたビューではなく、ウィンドウの寸法を提供します。これはどのように関連していますか?
Mark Amery

1
@MarkAmeryウィンドウの寸法を使用して、ビューの外観を計画できます
Bruno Guerra

2
@BrunoGuerraあなたはディメンションによって特定のビュー(ウィンドウではない)サイズを取得するためのコードを表示できますか?
Spark.Bao 2016年

4
デバイスを回転させても、多くのデバイスで寸法が更新されません。これは既知の問題であり、react-native 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 2017年

-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.