React Native'de bir Görünümün boyutunu alma


148

Belirli bir görünümün boyutunu (genişlik ve yükseklik) elde etmek mümkün müdür? Örneğin, ilerlemeyi gösteren bir görünüm var:

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

Diğer görünümleri düzgün bir şekilde hizalamak için görünümün gerçek genişliğini bilmem gerekiyor. Mümkün mü?

Yanıtlar:


315

React Native 0.4.2 itibariyle, View bileşenlerinin bir onLayoutpervanesi vardır . Bir olay nesnesini alan bir işlevi iletin. Etkinlik nativeEvent, görünümün düzenini içerir.

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

onLayoutGörünümü yeniden boyutlandırılır zaman işleyici da çağrılır.

Ana uyarı, onLayoutişleyicinin ilk olarak bileşeniniz monte edildikten sonra bir kare çağrılmasıdır, bu nedenle düzeninizi hesaplayana kadar kullanıcı arayüzünüzü gizlemek isteyebilirsiniz.


2
Bu yaklaşımın sorunu, cihaz döndürüldüğünde / boyut değiştiğinde, tekrar çağrılamam.
Matthew

4
görünümün çerçevesi değiştiğinde onLayout çağrılır. Belki de bakış açınız boyutunu veya dönüşteki konumunu değiştirmez. UIExplorer'daki onLayout'un döndürüldüğünde çağrıldığı onLayout örneğine bakın.
ide

2
ViewBoyutlara bağlı olarak farklı bir şekilde görüntülemek istediğimi varsayalım . Görünümü görüntüleme biçimimi onLayoutdeğiştirmek için Görünüm işlevini nasıl kullanabileceğimi anlamıyorum . Bu sonsuz bir döngüye yol açmaz mı?
Lane Rettig

2
@LaneRettig Evet, eğer gerçekten yapmak istediğiniz buysa, kodunuzu statik dengeye ulaşacak şekilde yazmalısınız. Ancak, görünümünüzü ekran boyutlarına göre özelleştirmek isteyebileceğiniz gibi görünüyor, bu durumda onLayoutilgisiz.
ide

7
@ide Düzen hesaplanana kadar kullanıcı arayüzünü nasıl gizlersiniz?
Irfanlone

27

Benim için işe yarayan tek şey bu:

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

Temel olarak, boyutu ayarlamak ve değişmesini istiyorsanız, aşağıdaki gibi düzende belirtin:

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

Bunu başka bir görünümde sarmalayıcı olarak kullanan başka bir bileşende kullanarak nasıl değiştirileceğine ilişkin çok daha fazla varyasyon oluşturabilir ve dokunma olayı konumunu duruma geçirebilecek bir onResponderRelease geri çağrısı oluşturabilirsiniz. onLayout güncellenmiş durumunu geçersiz kılabilen özellik olarak yerleştirerek {[styles.View2, this.state.view2LayoutProps, this.props.touchEventTopLeft]}vb.


11

Doğrudan Dimensionsmodülü kullanabilir ve görünüm boyutlarınızı kireçleyebilirsiniz. Aslında, Dimensionssize ana pencere boyutlarını verin.

import { Dimensions } from 'Dimensions';

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

Size yardımcı olmayı umuyoruz!

Güncelleme : Bugün görünümlerinizde Flex düzenleme StyleSheetile yerel kullanmak , görünüm boyutlarınızı hesaplamak yerine geniş durumlarda zarif düzen çözümleriyle temiz kod yazmanıza yardımcı olur ...

Bir bina olmasına rağmen , özel ızgara bileşenleri , ana pencere boyutlandırma olaylara hangi cevap verir, basit Widget bileşenlerindeki iyi çözüm üretebilir


3
Gah, bu neden daha açık bir şekilde belgelenmemiş!?! ('Pencere') yerine 'genişlik' ve 'yükseklik'

273
Verdiğiniz örnek , belirli bir görünümün değil pencerenin boyutlarını sağlar ; bu nasıl alakalı?
Mark Amery

1
Pencere boyutları ile görüşlerinizin nasıl görüneceğini planlayabilirsiniz
Bruno Guerra

2
@BrunoGuerra, Boyutlara göre belirli bir görünüm (pencere değil) boyutu almak için kodu gösterebilir misiniz?
Spark.Bao

4
Cihaz döndürüldüğünde boyutlar birçok cihazda güncellenmez. Bu bilinen bir sorundur ve tepkime doğal 0.32.0-rc.0 itibariyle düzeltilmiş görünmemektedir
Glenn Lawrence

10

Belki şunları kullanabilirsiniz 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);
}

Hayatım boyunca doğru bir şekilde nasıl kullanılacağını anlayamıyorum NativeMethodsMixin. Ne yaparsam yapayım, measuredaima tanımsızdır. İşaretçi var mı?
chandlervdw

2
NativeMethodsMixinSadece bazı elemanlarda bu fonksiyonu kullanmanıza gerek yoktur . Örneğin TouchableWithFeedback, ölçü işlevi vardır, ancak normalde Touchableyoktur. Kullandığınız türü değiştirmeye çalışın View, ref'yi alın ve ölçü öğesinin kullanılabilir olup olmadığını kontrol edin. Ben de bunun üzerine tökezledim.
n0rm

-3

benim için çalışacak Boyutları% olarak kullanacak şekilde ayarlamak benim için width:'100%'


-4

İşte cihazın tam görünümünün Boyutlarını almak için kod.

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

Şöyle kullanın:

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


Bu iyi, ama soruya cevap vermiyor.
Moso Akinyemi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.