在上一章中React Native 之自定義下拉刷新中,已經(jīng)完成了對React Native中封裝與使用下拉刷新,但在實(shí)際項(xiàng)目中,經(jīng)常需要在下拉刷新中添加各種動(dòng)畫效果.
如下:
當(dāng)用戶往下拉時(shí),雞蛋的蛋殼 會(huì)往上移動(dòng);觸發(fā)刷新時(shí),播放一段雞蛋搖晃的動(dòng)畫效果;當(dāng)刷新完畢時(shí),雞蛋從上往下掉,最后蓋住雞蛋殼.
實(shí)現(xiàn)原理:
在React Native中要使用該效果,光靠js 可能是不夠的,光是播放 幀動(dòng)畫,React Native也沒有實(shí)現(xiàn)該效果的控件. 所以最簡單的辦法 是將雞蛋與蛋殼的邏輯都放入原生代碼中實(shí)現(xiàn), React Native端告訴原生代碼移動(dòng)的距離與狀態(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)用蛋殼向上移動(dòng)的原生方法*/
shellUpward:function(distance){
UIManager.dispatchViewManagerCommand(
this.getPluImageHandle(),
1,
[distance]
);
},
/**調(diào)用雞蛋搖動(dòng)幀動(dòng)畫的原生方法*/
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事件中使蛋殼移動(dòng)
if (lastMoveY===0){
lastMoveY=gestureState.y0;
}
//到了一定長度后,讓蛋殼上升
// >90 只有移動(dòng)到了視野可見范圍才開始移動(dòng)蛋殼
if (gestureState.dy>90){
//移動(dòng)的距離
let distance=gestureState.moveY-lastMoveY;
//計(jì)算總共的移動(dòng)距離
hasMovedDistance+=distance;
//調(diào)用原生代碼移動(dòng)蛋殼
self.refs[PLU_IMAGE_KEY].shellUpward(distance);
}
lastMoveY=gestureState.moveY;
lastMoveY
是記錄上次移動(dòng)的距離,distance
表示當(dāng)前需要移動(dòng)的距離,
gestureState.dy
是touchMove
方法返回的移動(dòng)路程.
在原生代碼中處理移動(dòng)
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
方法移動(dòng)蛋殼的布局.
本人項(xiàng)目中的運(yùn)行效果:
gif動(dòng)畫錄得不太好,導(dǎo)致最后的動(dòng)畫效果有跳躍性,敬請諒解.