Отримайте розмір представлення в React Native


147

Чи можна отримати розмір (ширину та висоту) певного виду? Наприклад, у мене є вид, який показує прогрес:

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

Мені потрібно знати фактичну ширину перегляду, щоб правильно вирівняти інші види. Чи можливо це?

Відповіді:


315

Станом на React Native 0.4.2, компоненти View мають onLayoutопору . Передайте функцію, яка приймає об'єкт події. Подія nativeEventмістить макет подання.

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

onLayoutОброблювач також буде викликатися щоразу , коли уявлення змінює розмір.

Основний застереження полягає в тому, що onLayoutобробник спочатку викликає один кадр після монтажу вашого компонента, тож ви можете заховати інтерфейс користувача, поки не обчислите ваш макет.


2
Проблема такого підходу полягає в тому, що коли пристрій обертається / переглядає зміни розміру, я не отримую виклику знову.
Матвій

4
onLayout викликається при зміні кадру перегляду. Можливо, ваш погляд не змінює свого розміру чи положення при обертанні. Подивіться приклад onLayout у UIExplorer, де onLayout викликається при повороті.
іде

2
Скажімо, я хочу відображати Viewінакше, залежно від розмірів. Я не розумію, як я можу використовувати функцію View onLayoutдля зміни способу відображення View. Чи це не призводить до нескінченного циклу?
Лейн Реттіг

2
@LaneRettig Так, якщо це дійсно те, що ви хочете зробити, то вам слід написати свій код таким чином, щоб досягти статичної рівноваги. Але це здається, що ви можете просто налаштувати свій погляд на основі розмірів екрана, в цьому випадку onLayoutце не пов’язано.
іде

7
@ide як би ви приховали інтерфейс користувача, поки не буде розраховано макет?
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, який міг би передати розташування сенсорного події у стан, який потім може бути переданий дочірньому компоненту як властивість, яка могла б змінити стан оновленого макета, розмістивши {[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
Гах, чому це не документоване більш чітко!?! Я намагався замість ('вікна') ширини і 'ширини' та 'висоти', і т.д.

272
Наведений вами приклад містить розміри вікна , а не заданого виду; наскільки це актуально?
Марк Амері

1
@MarkAmery за допомогою розмірів вікон ви можете планувати, як виглядатимуть ваші погляди
Бруно Гуерра

2
@BrunoGuerra чи можете ви показати код, щоб отримати певний розмір подання (а не вікна) за розмірами?
Спарк.Байо

4
Розміри не оновлюються на багатьох пристроях при поверненні пристрою. Це відома проблема і, здається, не виправлена ​​як у реакції на рідну реакцію 0,32,0-rc.0
Глен Лоуренс

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


Це нормально, але це не відповідає на питання.
Мосо Акініємі,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.