【问题标题】:React-Native animate height changeReact-Native 动画高度变化
【发布时间】:2018-09-13 04:23:59
【问题描述】:

我有一个 React-Native 组件,其大小由必须从 Internet 加载的内容决定。随着加载的进行,它的大小会发生一些变化,我希望它看起来更平滑一些。

我现在做的哪种工作是在我从 onLayout 获得新高度后为视图的 scaleY 属性设置动画。问题是我只能在onLayout之后设置动画的初始比例,所以有一会儿,视图是新​​尺寸,然后开始从旧尺寸动画到新尺寸。

如果有一种方法可以在渲染之前获得新的布局大小,那就太棒了,但我找不到这样做的方法。

另一种选择是将视图放在另一个视图中,将其剪辑到旧高度,直到可以调整其比例,但我不知道如何在不影响视图本身大小的情况下执行此操作。剪辑的那一刻可能也会以自己的方式看起来很奇怪。

【问题讨论】:

  • 我不确定它是否会起作用,但是您可以尝试在屏幕外使用position: absolute 渲染此视图,然后对其进行测量并获得新的尺寸。希望这会有所帮助
  • @savelichalex 我也考虑过渲染幽灵,但我对这个应用程序并不疯狂,因为我这里有一些相当繁重的渲染。

标签: react-native


【解决方案1】:

我最近回答了一个类似这个问题的问题:
How do you animate the height in react native when you don't know the size of the content?

但我会再次在这里发布答案。
对于您的情况,请在加载内容后尝试运行 animate 函数。


大家好,希望还不算太晚...

适用于在视图高度上处理 React Native 动画的任何人。
我知道这很烦人:

✖️React Native动画似乎不支持布局样式(例如宽度和高度)
✖️ LayoutAnimation 看起来很难调查
✖️ 希望用官方的方式制作动画而不是安装第三方包
✖️ 有时内容可能会影响您的视图样式

所以这是我给你的解决方案(类组件方式):

首先,在状态中设置动画值:

state = { height: new Animated.Value(0) };

接下来,使用动画插值设置动画视图的 max height

const maxHeight = this.state.height.interpolate({ 
  inputRange: [0, 1], 
  outputRange: [0, 2000]  // <-- any value larger than your content's height
};
return (<Animated.View style={[styles.box, { maxHeight: maxHeight }]} />); 
// any other fixed styles in styles.box

然后,在你调用的function 中设置动画,
componentDidMount 如果您希望它在渲染后立即显示:

// or in any function that users interact
componentDidMount() {
  Animated.timing(this.state.formHeight, {
    toValue: 1,
    duration: 500,           // <-- animation duration
    easing: Easing.linear,   // <-- or any easing function
    useNativeDriver: false   // <-- need to set false to prevent yellow box warning
  }).start();
}

请注意不要将 useNativeDriver 设置为 true,因为布局样式不支持它。


示例

下面是一个供您互动的示例,
随意复制并粘贴到您的 React Native 项目中尝试一下:

import React, { PureComponent } from 'react';
import { Animated, Button, Easing, View, Text, StyleSheet } from 'react-native';

class AnimateBox extends PureComponent {
  state = { opacity: new Animated.Value(0), height: new Animated.Value(0) };

  showContent = () => {
    const { opacity, height } = this.state;

    Animated.timing(height, {
      toValue: 1,
      duration: 500,
      easing: Easing.linear,
      useNativeDriver: false  // <-- neccessary
    }).start(() => {
      Animated.timing(opacity, {
        toValue: 1,
        duration: 500,
        easing: Easing.linear,
        useNativeDriver: false  // <-- neccessary
      }).start();
    });
  };

  render() {
    const { opacity, height } = this.state;
    const maxHeight = height.interpolate({ 
      inputRange: [0, 1], 
      outputRange: [0, 1000]  // <-- value that larger than your content's height
    });

    return (
      <View style={styles.box}>
        <Animated.View style={{ opacity: opacity, maxHeight: maxHeight }}>
          <Text style={styles.content}>
            Lorem Ipsum is simply a dummy text of the printing and typesetting industry.
            Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
            when an unknown printer took a galley of type and scrambled it to make a type specimen book.
            It has survived not only five centuries, but also the leap into electronic typesetting,
            remaining essentially unchanged. It was popularised in the 1960s with the release of
            Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
          </Text>
        </Animated.View>
        <View style={styles.spacing}>
          <Button title="Show content" onPress={this.showContent} />
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  box: {
    backgroundColor: '#fff',
    marginHorizontal: 15,
    paddingHorizontal: 15
  },
  spacing: {
    paddingVertical: 10
  },
  content: {
    fontSize: 16,
    lineHeight: 30,
    color: '#555'
  }
});


export default AnimateBox;

快乐编码:)

【讨论】:

    猜你喜欢
    • 2022-01-19
    • 2015-02-27
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 2022-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多