根据动态数据

时间:2017-09-15 17:22:12

标签: reactjs react-native

背景

我有一个父组件,它是一张折叠卡。当它通过子组件并在扩展时显示它,它将在滚动框中呈现。我尝试使用

调整组件扩展时的高度
Dimensions.get('window').height

但问题在于它使卡片成为页面高度。我需要它是孩子的​​数据加上一些填充的高度。

示例

class CardCollapsible extends Component {
    constructor(props) {
        super(props);

        this.state = {
            title: props.title,
            expanded: this.props.expanded,
            animation: new Animated.Value(),
            icon: this.props.icon,
            iconStyles: this.props.iconStyles,
        };

        this.anime = {
            height: new Animated.Value(),
            expanded: false,
            contentHeight: 0,
        };

        this._initContentHeight = this._initContentHeight.bind(this);
        this.getIconStyles = this.getIconStyles.bind(this);
        this.toggle = this.toggle.bind(this);
        this.anime.expanded = props.expanded;
        this.minValue = props.minValue;
        this.openIconStyles = props.openIconStyles;
        this.closedIconStyles = props.closedIconStyles;
    }

    componentWillMount() {
        this.getIconStyles();
    }

    getIconStyles() {
        let iconStyles = null;
        let icon = null;
        if (this.state.expanded) {
            iconStyles = _.extend({}, this.props.closedIconStyles);
            icon = this.props.iconClose;
        } else {
            iconStyles = _.extend({}, this.props.openIconStyles);
            icon = this.props.iconOpen;
        }

        const expanded = !this.state.expanded;
        this.setState({ iconStyles, icon, expanded });
    }

    _initContentHeight(evt) {
        if (this.anime.contentHeight <= 0) {
            this.anime.contentHeight = evt.nativeEvent.layout.height;
            this.anime.height.setValue(this.anime.expanded ? this._getMaxValue() : this._getMinValue());
        }
    }

    _getMaxValue() { return this.anime.contentHeight + 30; }
    _getMinValue() { return this.props.minValue; }

    toggle() {
        this.getIconStyles();

        Animated.timing(this.anime.height, {
            toValue: this.anime.expanded ? this._getMinValue() : this._getMaxValue(),
            duration: 300,
        }).start();
        this.anime.expanded = !this.anime.expanded;
    }

    render() {
        return (
            <Card style={styles.container}>
                <View style={styles.titleContainer}>
                    <CardTitle>{this.state.title}</CardTitle>
                    <TouchableHighlight
                        style={styles.button}
                        onPress={this.toggle}
                        underlayColor="#f1f1f1"
                    >
                        <Icon
                            name={this.state.icon}
                            style={[this.state.iconStyles, styles.icon]}
                        />
                    </TouchableHighlight>
                </View>

                <Animated.View style={{ height: this.anime.height }} onLayout={this._initContentHeight}>
                    <Separator />
                    <CardContent style={styles.CardContent}>
                        {this.props.children}
                    </CardContent>
                </Animated.View>
            </Card>
        );
    }
}

使用CardCollapsible组件。

展开卡片时,数据会在滚动中呈现。

<CardCollapsible>
   <FlatList>...</FlatList>
</CardCollapsible>

然后将这些行更改为

Dimensions.get('window').height

它占据了屏幕的高度而不会关闭。

_initContentHeight(evt) {
        if (this.anime.contentHeight <= 0) {
            this.anime.contentHeight = evt.nativeEvent.layout.height;
            this.anime.height.setValue(this.anime.expanded ? this._getMaxValue() : this._getMinValue());
        }
    }

    _getMaxValue() { return Dimensions.get('window').height; }
    _getMinValue() { return this.props.minValue; }

问题

如何在渲染时根据子图数据将卡的高度更改为动态?

1 个答案:

答案 0 :(得分:1)

你想做的是一种常见的做法,但很棘手,因为反应不允许从孩子到父母的沟通。

我是如何完成的?使用ref.measures函数。我们来看看。

子实施:

export default class MyChild extends Component {
  render() {
    return (
      <TouchableWithoutFeedback onPress={this._onPress} ref={ref => this._options = ref}>

      </TouchableWithoutFeedback>
    );
  }

  _onPress() {
    this._options.measure((fx, fy, width, height, px, py) => {
      if (this.props.setMeasuresOnParent)
        this.props.setMeasuresOnParent({
          relativeX: fx,
          relativeY: fy,
          absoluteX: px,
          absoluteY: py,
          height,
          width
        });
    });
  }
}

父实施:

<MyChild
  setMeasuresOnParent={measures => this.props.showChildren(children_id?, measures.absoluteX, measures.absoluteY)}
/>

在我的情况下,我使用了Button样式的孩子,但您也可以在孩子身上使用componentDidMount告诉父母其措施。