【问题标题】:react-native making status bar animatedreact-native 制作状态栏动画
【发布时间】:2020-04-21 01:09:57
【问题描述】:

最初,我有一个带有light-content barStyle 的黑色背景,但是当我向上滚动时,背景颜色变为白色,我想将 statusBar barStyle 更改为“dark-content”。

这就是我试图让我的 statusBar 动画的原因。

到目前为止,我已经尝试过这样的:

  1. 我制作了 statusBar 动画组件

    const AnimatedStatusBar = Animated.createAnimatedComponent(StatusBar)

  2. 设置动画输入/输出范围

    scroll = new Animated.Value(0)

    statusBarColor = this.scroll.interpolate({ inputRange: [0, SCROLL_HEIGHT], outputRange: ['white', 'black'], extrapolate: "clamp" })

  3. 有条件地改变 barstyle。

    <AnimatedStatusBar backgroundColor='white' barStyle={this.statusBarColor ==='white'? 'light-content':'dark-content'} />

但是,这不起作用。如何使 statusBar 动画化,以便在滚动到顶部时更改 barStyle

【问题讨论】:

    标签: react-native


    【解决方案1】:

    iOS

    1. 我将<StatusBar/> 道具translucent 更改为true
    2. animated 支持 <StatusBar/> 为 true
    3. useSafeArea钩子的顶部获取状态栏高度
    4. 创建简单的Animated.View 具有100% width 和状态栏height

    安卓

    1. Animated.createAnimatedComponent(StatusBar); 创建AnimatedStatusBar

    其他步骤相同

    import { useSafeArea } from 'react-native-safe-area-context';
    
    const AnimatedStatusBar = Animated.createAnimatedComponent(StatusBar);
    function Page() {
      const { top: safeAreaTop } = useSafeArea();
      const barColorAnim = useRef(new Animated.Value(0)).current;
      const barColor = barColorAnim.interpolate({
        inputRange: [0, 1],
        outputRange: ['black', 'white'],
      });
      const [barStyle, setBarStyle] = useState('light-content');
    
      const toggle = () => {
        setBarStyle((style) =>
          style === 'light-content' ? 'dark-content' : 'light-content',
        );
        Animated.timing(barColorAnim, {
          useNativeDriver: false,
          duration: 300,
          toValue: barStyle === 'light-content' ? 1 : 0,
        }).start();
      };
    
      return (
        <Container>
          <Animated.View
            style={{
              width: '100%',
              height: safeAreaTop,
              backgroundColor: barColor,
            }}
          />
          <AnimatedStatusBar
            animated={true}
            backgroundColor={barColor}
            barStyle={barStyle}
            translucent={true}
          />
          <Button title="Toggle" onPress={toggle} />
        </Container>
      );
    }
    

    【讨论】:

    • 非常感谢您的回答!你能告诉我如何在没有钩子的情况下做到这一点吗?
    • 与类组件差别不大。您可以将useState 理解为this.statethis.setState 并且,关于useSafeArea,您可以参考此repo&lt;SafeAreaProvider&gt;&lt;/SafeAreaProvider 包装您的组件并将您的组件的上下文设置为SafeAreaContext,您可以获得safeArea top height 和useRef,这只是在构造函数中将Animated.Value 设置为类字段另外,我强烈建议您学习功能组件和钩子!太棒了
    • 为什么你在 Android 上做的不一样?
    • @HenriqueBruno 似乎动画={true} 在 Android 中不起作用
    • JFYI 我在 Android 上没有任何问题
    【解决方案2】:
    import { View, TouchableOpacity, Animated, StatusBar, Text } from 'react-native';
    import { SafeAreaProvider } from 'react-native-safe-area-context';
    
    const AnimatedStatusBar = Animated.createAnimatedComponent(StatusBar);
    const barColorAnim = new Animated.Value(0);
    const barColor = barColorAnim.interpolate({
        inputRange: [0, 1],
        outputRange: ['black', 'white'],
    });
    
    export class App extends React.Component {
    this.state = {
        barStyle: 'light-content'
    };
    
    render() {
        const toggle = () => {
            this.setState({
                barStyle: this.state.barStyle === 'light-content' ? 'dark-content' : 'light-content'
            })
            Animated.timing(barColorAnim, {
                useNativeDriver: false,
                duration: 300,
                toValue: this.state.barStyle === 'light-content' ? 1 : 0,
            }).start();
        };
    
        return (
            <>
                <SafeAreaProvider>
                    <AnimatedStatusBar
                        animated={true}
                        backgroundColor={barColor}
                        barStyle={this.state.barStyle}
                        translucent={true}
                    />
    
                    <TouchableOpacity
                        onPress={toggle}><Text>Click toggle</Text></TouchableOpacity>
                </SafeAreaProvider>
            </>
        );
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-19
      • 2019-03-02
      • 1970-01-01
      • 2022-11-08
      • 2019-06-18
      • 1970-01-01
      • 2022-10-14
      • 2017-10-10
      相关资源
      最近更新 更多