Nhận kích thước của Chế độ xem trong React Native


147

Có thể lấy kích thước (chiều rộng và chiều cao) của một chế độ xem nhất định không? Ví dụ: tôi có chế độ xem hiển thị tiến trình:

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

Tôi cần biết chiều rộng thực tế của khung nhìn để căn chỉnh các khung nhìn khác đúng cách. Điều này có thể không?

Câu trả lời:


315

Tính đến Phản ứng Native 0.4.2, Xem thành phần có một onLayoutchỗ dựa . Truyền vào một hàm có một đối tượng sự kiện. Sự kiện này nativeEventchứa bố cục của khung nhìn.

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

Trình onLayoutxử lý cũng sẽ được gọi bất cứ khi nào thay đổi kích thước khung nhìn.

Thông báo chính là onLayouttrình xử lý đầu tiên được gọi một khung sau khi thành phần của bạn được gắn kết, vì vậy bạn có thể muốn ẩn giao diện người dùng của mình cho đến khi bạn đã tính toán bố cục của mình.


2
Vấn đề của phương pháp này là khi thiết bị quay / thay đổi kích thước xem, tôi không nhận được gọi lại vào ngày.
Matthew

4
onLayout được gọi khi khung của khung nhìn thay đổi. Có lẽ chế độ xem của bạn không thay đổi kích thước hoặc vị trí của nó khi xoay. Nhìn vào ví dụ onLayout trong UIExplorer, trong đó onLayout được gọi khi xoay vòng.
ide

2
Giả sử tôi muốn hiển thị Viewkhác nhau tùy thuộc vào kích thước. Tôi không hiểu làm thế nào tôi có thể sử dụng onLayoutchức năng của Chế độ xem để thay đổi cách tôi hiển thị Chế độ xem. Điều đó không dẫn đến một vòng lặp vô hạn?
Lane Rettig

2
@LaneRettig Có, nếu nó thực sự là những gì bạn muốn làm, thì bạn nên viết mã của mình theo cách đạt đến trạng thái cân bằng tĩnh. Nhưng có vẻ như bạn chỉ muốn tùy chỉnh chế độ xem của mình dựa trên kích thước màn hình trong trường hợp onLayoutkhông liên quan.
ide

7
@ide bạn sẽ ẩn UI như thế nào cho đến khi bố cục được tính toán?
Irfanlone

27

Đây là điều duy nhất làm việc cho tôi:

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

Về cơ bản nếu bạn muốn đặt kích thước và làm cho nó thay đổi thì hãy đặt nó thành trạng thái trên bố cục như thế này:

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

Bạn có thể tạo thêm nhiều biến thể về cách cần sửa đổi, bằng cách sử dụng phần này trong một thành phần khác có chế độ xem khác làm trình bao bọc và tạo một cuộc gọi lại onResponderRelease, có thể chuyển vị trí sự kiện chạm vào trạng thái, sau đó có thể được chuyển đến thành phần con là tài sản, có thể ghi đè lên trạng thái cập nhật trên trang, bằng cách đặt {[styles.View2, this.state.view2LayoutProps, this.props.touchEventTopLeft]}và cứ thế.


11

Bạn có thể trực tiếp sử dụng Dimensionsmô-đun và calc kích thước lượt xem của bạn. Trên thực tế, Dimensionscung cấp cho bạn các kích thước cửa sổ chính.

import { Dimensions } from 'Dimensions';

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

Hy vọng sẽ giúp bạn!

Cập nhật : Hôm nay, sử dụng nguồn gốc StyleSheetvới Flex sắp xếp theo quan điểm của bạn giúp viết mã sạch với các giải pháp bố cục trang nhã trong trường hợp rộng thay vì tính toán kích thước chế độ xem của bạn ...

Mặc dù việc xây dựng một thành phần lưới tùy chỉnh , đáp ứng với các sự kiện thay đổi kích thước cửa sổ chính, có thể tạo ra một giải pháp tốt trong các thành phần widget đơn giản


3
Gah, tại sao điều này không được ghi chép rõ ràng hơn!?! Tôi đã thử 'chiều rộng' và 'chiều cao' thay vì ('cửa sổ'). Chiều rộng, v.v.

272
Ví dụ bạn đã cung cấp cung cấp kích thước của cửa sổ , không phải của chế độ xem đã cho; cái này có liên quan như thế nào?
Đánh dấu Amery

1
@MarkAmery với kích thước cửa sổ, bạn có thể lập kế hoạch cho chế độ xem của mình sẽ như thế nào
Bruno Guerra

2
@BrunoGuerra bạn có thể hiển thị mã để có kích thước chế độ xem (không phải cửa sổ) nhất định theo Kích thước không?
Spark.Bao

4
Kích thước không được cập nhật trên nhiều thiết bị khi thiết bị được xoay. Đây là một vấn đề đã biết và dường như không được khắc phục kể từ phiên bản gốc 2.32.0-rc.0
Glenn Lawrence

10

Có lẽ bạn có thể sử dụng 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);
}

Đối với cuộc sống của tôi, tôi không thể tìm ra cách sử dụng đúng cách NativeMethodsMixin. Bất kể tôi làm gì, measureluôn luôn không xác định. Bất kỳ con trỏ?
chandlervdw

2
Bạn không cần sử dụng NativeMethodsMixinchức năng chỉ có sẵn trên một số yếu tố. Ví dụ, TouchableWithFeedbackkhông có chức năng đo, nhưng thông thường Touchablethì không. Hãy thử thay đổi loại Viewbạn đang sử dụng, lấy ref và kiểm tra xem phần tử đo có khả dụng không. Tôi đã vấp ngã trên này là tốt.
n0rm

-3

đối với tôi, đặt Kích thước để sử dụng% là những gì hiệu quả với tôi width:'100%'


-4

Dưới đây là mã để có được Kích thước của chế độ xem hoàn chỉnh của thiết bị.

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

Sử dụng nó như thế này:

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


Điều này không sao, nhưng nó không trả lời câu hỏi.
Moso Akinyemi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.