Dapatkan ukuran Tampilan di Bereaksi Asli

147

Apakah mungkin untuk mendapatkan ukuran (lebar dan tinggi) dari tampilan tertentu? Misalnya, saya memiliki pandangan yang menunjukkan kemajuan:

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

Saya perlu tahu lebar sebenarnya dari tampilan untuk menyelaraskan tampilan lain dengan benar. Apakah ini mungkin?

Matius
sumber

Jawaban:

315

Pada Bereaksi Asli 0.4.2, Lihat komponen memiliki onLayoutpenyangga . Mengirimkan fungsi yang mengambil objek acara. Acara ini nativeEventberisi tata letak tampilan.

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

The onLayouthandler juga akan dipanggil setiap kali pandangan adalah ukurannya.

Peringatan utama adalah bahwa onLayoutpawang pertama kali dipanggil satu frame setelah komponen Anda dipasang, jadi Anda mungkin ingin menyembunyikan UI Anda sampai Anda telah menghitung tata letak Anda.

ide
sumber
2
Masalah dari pendekatan ini adalah ketika perangkat memutar / melihat perubahan ukuran, saya tidak dipanggil onLayout lagi.
Matius
4
onLayout dipanggil saat bingkai tampilan berubah. Mungkin tampilan Anda tidak mengubah ukuran atau posisinya pada rotasi. Lihatlah contoh onLayout di UIExplorer, di mana onLayout dipanggil saat rotasi.
ide
2
Katakanlah saya ingin menampilkan yang Viewberbeda tergantung pada dimensi. Saya tidak mengerti bagaimana saya bisa menggunakan fungsi Tampilan onLayoutuntuk mengubah cara saya menampilkan Tampilan. Bukankah itu mengarah ke loop tak terbatas?
Lane Rettig
2
@LaneRettig Ya itu melakukannya jika ini benar-benar yang ingin Anda lakukan, maka Anda harus menulis kode Anda dengan cara yang mencapai keseimbangan statis. Tapi sepertinya Anda hanya ingin menyesuaikan tampilan berdasarkan dimensi layar yang onLayouttidak terkait.
ide
7
@ samping bagaimana Anda menyembunyikan UI sampai tata letak dihitung?
Irfanlone
27

Ini adalah satu-satunya hal yang berhasil untuk saya:

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);
Abhishek Kumar
sumber
14

Pada dasarnya jika Anda ingin mengatur ukuran dan membuatnya berubah maka aturlah untuk menyatakan tata letak seperti ini:

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);

Anda dapat membuat lebih banyak variasi tentang bagaimana hal itu harus dimodifikasi, dengan menggunakan ini di komponen lain yang memiliki tampilan lain sebagai pembungkus dan membuat panggilan balik onResponderRelease, yang dapat melewati lokasi acara sentuh ke keadaan, yang kemudian dapat diteruskan ke komponen anak sebagai properti, yang dapat mengesampingkan keadaan diperbarui onLayout, dengan menempatkan {[styles.View2, this.state.view2LayoutProps, this.props.touchEventTopLeft]}dan sebagainya.

juslintek
sumber
11

Anda dapat langsung menggunakan Dimensionsmodul dan menghitung ukuran tampilan Anda. Sebenarnya, Dimensionsberikan kepada Anda ukuran jendela utama.

import { Dimensions } from 'Dimensions';

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

Semoga dapat membantu Anda!

Pembaruan : Hari ini menggunakan yang asli StyleSheetdengan Flex mengatur pandangan Anda membantu menulis kode bersih dengan solusi tata letak yang elegan dalam banyak kasus, bukannya menghitung ukuran tampilan Anda ...

Meskipun membangun komponen kisi khusus , yang merespons peristiwa pengubahan ukuran jendela utama, dapat menghasilkan solusi yang baik dalam komponen widget sederhana

Bruno Guerra
sumber
3
Gah, mengapa ini tidak didokumentasikan dengan lebih jelas!?! Saya mencoba 'lebar' dan 'tinggi' alih-alih ('jendela'). Lebar dll.
272
Contoh yang Anda berikan memberikan dimensi jendela , bukan tampilan yang diberikan; bagaimana ini relevan?
Mark Amery
1
@MarkAmery dengan dimensi jendela, Anda dapat merencanakan tampilan seperti apa
Bruno Guerra
2
@ BrunoGuerra dapatkah Anda menampilkan kode untuk mendapatkan ukuran tampilan tertentu (bukan jendela) berdasarkan Dimensi?
Spark.Bao
4
Dimensi tidak diperbarui pada banyak perangkat saat perangkat diputar. Ini adalah masalah yang diketahui dan tampaknya tidak diperbaiki seperti pada reaksi asli 0.32.0-rc.0
Glenn Lawrence
10

Mungkin Anda bisa menggunakan 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);
}
Yinfeng
sumber
Untuk kehidupan saya, saya tidak tahu cara menggunakannya dengan benar NativeMethodsMixin. Apa pun yang saya lakukan, measureselalu tidak terdefinisi. Ada petunjuk?
chandlervdw
2
Anda tidak perlu menggunakan NativeMethodsMixinfungsi ini hanya tersedia pada beberapa elemen. Misalnya TouchableWithFeedbackmemang memiliki fungsi ukuran, tetapi yang biasa Touchabletidak. Cobalah untuk mengubah jenis yang ViewAnda gunakan, dapatkan referensi dan periksa apakah elemen ukuran tersedia. Saya juga menemukan ini.
n0rm
-3

bagi saya mengatur Dimensi untuk menggunakan% adalah apa yang berhasil bagi saya width:'100%'

pinchez254
sumber
-4

Berikut adalah kode untuk mendapatkan Dimensi dari tampilan lengkap perangkat.

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

Gunakan seperti ini:

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

ravi
sumber
Ini baik-baik saja, tetapi tidak menjawab pertanyaan.
Moso Akinyemi