[ 卡卡 DAY 16 ] - React Native Animated 入门 + useNativeDriver 好棒棒

React Native 提供了 Animated 及 LayoutAnimation API
给使用者有良好的体验加点动画是必须的

Animated API

概念

Animated 是 React Native 原生的套件,可以运用内建的 func 来控制动画使动画变得更流畅。
通过绑定 Animated.Value 到 View 的 styles 或者 props 上,然後通过 Animated.timing() ... 等方法操作 Animated.Value 进而更新动画。

  • Animated.event() 关联 Animated.Value 到某一个 View 的事件上
  • Animated.Value() 用於单个值
  • Animated.ValueXY() 用於矢量值
  • useNativeDriver 使用之後,页面更新就没有 JS 的参与,直接都在 Native 的 UI 线程渲染。

Animated.Valued 可以绑定样式,也可以进行插值运算。单个 Animated.Value 可以用在任意多个属性上。
深入请看doc

动画配置

其实跟 css 的动画很像,Animated 提供了三种动画类型:

  1. Animated.decay() 初始数度越来越来再来停下
  2. Animated.spring() 弹簧效果
  3. Animated.timing() 使用 easing 函数让数值随时间动起来

大家都比较常使用 timing()。default 时 easeInOut 曲线,指定物会逐渐变快到指定数度然後慢慢减慢到停止。
运用 start() 开始
运用 stop() 结束

Animated.timing({}).start(({ finished }) => {
  /* 动画完成的数值 */
});

开始前先来讲一下 useNativeDriver(bool)

这是含在动画配置里面的参数,主要是启用原生动画的驱动。

什麽意思呢?需要用吗?哪个比较好呢?

在 React Native 当动画运转时有两个情形:

  • JS tread 计算 + Animation by Native OS (useNativeDriver:false)
  1. compute
  2. serialize
  3. transfer it over the bridge to host OS
  4. deserialize
  5. run the frame
  • Everything by Native OS (useNativeDriver:true)
  1. before your animation starts -> serialize whole animation thing
  2. Native OS would deserialize it

相对起来使用 useNativeDriver:true 的步骤少了很多,实际的优势有以下:

  1. no more over the bridge transfers
  2. JS thread is now free for other stuff
  3. smoother animations

所以建议使用 useNativeDriver:true 唷!可参考这影片验证给你看~~

一二三照着做简单动画

实作前提
useRef:参考变数,只要 App 没有完全关闭,useRef 记录的参考变数就不会消失(类似於全域变数的效果)
useEffect:componentDidMount 阶段

  1. 於 components/ 建一个 AnimatedFade.js

    import { Animated } from 'react-native';
    import React, { useRef, useEffect } from "react";
    
  2. 设定初始值

    const fadeIn = useRef(new Animated.Value(0)).current;
    
  3. 使用一个 Animated.View 来显示画面 return

     <Animated.View
       style={{
         ...props.style,
         opacity: fadeIn,
       }}>
       {props.children}
     </Animated.View>
    
  4. 於 useEffect 画面一进来时做出动画的效果

    useEffect(() => {
        Animated.timing(fadeIn, {
             toValue: 1,
             duration: 1000,
             useNativeDriver: true,
        }).start();
    }, [fadeIn]);
    
    

完整的 AnimatedFade.js

```
import React, {useRef, useEffect} from 'react';

import {Animated} from 'react-native';
const AnimatedFade = props => {
const fadeIn = useRef(new Animated.Value(0)).current;

useEffect(() => {
Animated.timing(fadeIn, {
    toValue: 1,
    duration: 3000,
    useNativeDriver: true,
    }).start();
}, [fadeIn]);

return (
    <Animated.View
    style={{
        ...props.style,
            opacity: fadeIn,
    }}>
        {props.children}
    </Animated.View>
    );
};

export default AnimatedFade;
```
  1. 於 Screens/ 建立 AnimatedScreen.js

     import React from 'react';
     import {View, Text, StyleSheet, Image} from 'react-native';
     import AnimatedFade from '../components/AnimatedFade';
     import {assets} from '../constants';
    
     const IconScreen = () => {
         return (
         <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
             <AnimatedFade>
                 <Image source={assets.water} />
                 <Text style={styles.text}>我出现噜!</Text>
             </AnimatedFade>
         </View>
         );
     };
     const styles = StyleSheet.create({
         text: {
             width: 300,
             height: 30,
             textAlign: 'center',
             lineHeight: 30,
             backgroundColor: 'pink',
         },
     });
    
     export default IconScreen;
    
  2. 并用之前 navigation 教的把页面放入 stack 中即可看到动画拉!!!

https://ithelp.ithome.com.tw/upload/images/20210929/20142011qUT9SCN75k.jpg

https://ithelp.ithome.com.tw/upload/images/20210929/20142011kftDaq63jr.jpg
基於还不知道怎麽用 gif 上来

所以请大家看我按了那个动画按钮之後西瓜就慢慢的 fade 进来拉 <3

Day 17 done 简单的 Animated,请多多指教~


<<:  DAY16-EXCEL统计分析:Z检定实例

>>:  密码学基础篇

Day 05 CSS <基础选择器>

CSS的选择器分为基础选择器以及复合选择器 本日将先说明基础选择器 DAY6将继续说明复合选择器 C...

Feedly 和 Inoreader,用RSS阅读器蒐集实用数位行销blog推荐资讯

这个实用网路行销工具系列文,将会整理我平常研究的各项网路行销工具,帮助工程师如果有现成的服务可以快速...

【LeetCode】Array

本文会提到做 array 常犯错误、如何避免,与常见的技巧。 此系列 Leetcode 篇不介绍基本...

Day27 简易小键盘小实作2

接续昨天 我们在按钮的action里加入这段程序码, 变数tag-1的部分就是按下1时呈现的数字是刚...

Day027-透过Vuex-实作简易部落格-列举及删除文章

Vue:昨日,我们已将文章新增实做出来了!现在只要将文章列举在首页,只需要使用之前学到的v-for回...