React Native 下拉刷新添加自定義動畫

在上一章中React Native 之自定義下拉刷新中,已經(jīng)完成了對React Native中封裝與使用下拉刷新,但在實(shí)際項(xiàng)目中,經(jīng)常需要在下拉刷新中添加各種動畫效果.

如下:


當(dāng)用戶往下拉時(shí),雞蛋的蛋殼 會往上移動;觸發(fā)刷新時(shí),播放一段雞蛋搖晃的動畫效果;當(dāng)刷新完畢時(shí),雞蛋從上往下掉,最后蓋住雞蛋殼.

實(shí)現(xiàn)原理:
在React Native中要使用該效果,光靠js 可能是不夠的,光是播放 幀動畫,React Native也沒有實(shí)現(xiàn)該效果的控件. 所以最簡單的辦法 是將雞蛋與蛋殼的邏輯都放入原生代碼中實(shí)現(xiàn), React Native端告訴原生代碼移動的距離與狀態(tài).

關(guān)鍵代碼:

封裝View ,使用UIManager.dispatchViewManagerCommand調(diào)用View的方法.

var React = require('React');
var ReactNative = require('ReactNative');
var requireNativeComponent = require('requireNativeComponent');

var UIManager = require('UIManager');
import {
    View,
} from 'react-native';

const PK_REF_KEY="pk_ref_key";

var PluImageLayout =React.createClass({

    propTypes: {
        ...View.propTypes,
    },
    /**調(diào)用蛋殼向上移動的原生方法*/
    shellUpward:function(distance){
        UIManager.dispatchViewManagerCommand(
            this.getPluImageHandle(),
            1,
            [distance]
        );
    },
    /**調(diào)用雞蛋搖動幀動畫的原生方法*/
    loadingAnim:function () {
        UIManager.dispatchViewManagerCommand(
            this.getPluImageHandle(),
            2,
            null
        );
    },
    /**調(diào)用恢復(fù)蛋殼位置的原生方法*/
    resetShell:function (distance,maxLength,maxTime) {
        UIManager.dispatchViewManagerCommand(
            this.getPluImageHandle(),
            3,
            [distance,maxLength,maxTime]
        );
    },

    render:function () {
        return (
            <RCTPluImageLayout
                style={{width:38,height:70,marginRight:10,marginTop:-20}}
                ref={PK_REF_KEY}
            >
            </RCTPluImageLayout>
        );
    },
    /**找到控件的節(jié)點(diǎn)*/
    getPluImageHandle: function() {
        return ReactNative.findNodeHandle(this.refs[PK_REF_KEY]);
    },
});

var RCTPluImageLayout = requireNativeComponent('AndroidPluImageLayout', PluImageLayout);

module.exports = PluImageLayout;

在React Native的touchMove事件中使蛋殼移動

        if (lastMoveY===0){
            lastMoveY=gestureState.y0;
        }
        //到了一定長度后,讓蛋殼上升
        //  >90 只有移動到了視野可見范圍才開始移動蛋殼
        if (gestureState.dy>90){
            //移動的距離
            let distance=gestureState.moveY-lastMoveY;
            //計(jì)算總共的移動距離
            hasMovedDistance+=distance;
            //調(diào)用原生代碼移動蛋殼
            self.refs[PLU_IMAGE_KEY].shellUpward(distance);
        }
        lastMoveY=gestureState.moveY;

lastMoveY是記錄上次移動的距離,distance表示當(dāng)前需要移動的距離,
gestureState.dytouchMove方法返回的移動路程.

在原生代碼中處理移動

double topMargin=iv_shell.getTop();
topMargin-=args.getDouble(0)*FACTOR;
iv_shell.layout(iv_shell.getLeft(),getIntValue(topMargin),iv_shell.   getRight(),iv_shell.getBottom());

使用view.layout方法移動蛋殼的布局.

本人項(xiàng)目中的運(yùn)行效果:

gif動畫錄得不太好,導(dǎo)致最后的動畫效果有跳躍性,敬請諒解.

完整代碼下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容