介绍
公司的项目中包含IM模块,其中包含红包功能,在做打开红包的时候,觉得打开的按钮若不旋转感觉太过单调,没有乐趣,所以参考微信的红包,打开的时候,“开”字旋转起来。这里主要用的是帧动画,先上效果图:
旋转动画的实现
一开始做的时候使用的是AnimationDrawable,定义animation-list,,尽管可以实现如上的结果,但是发现动画并没有特别流畅,有些卡顿,最后在github上找到了FrameAnimation,其设计思路是将图片资源用数组存储,然后通过设定的周期,遍历切换,这样在性能上比使用AnimationDrawable高,消耗内存较小,动画也相对比较流畅。
FrameAnimation的使用
定义图片资源的数组
private int[] mImgResIds = new int[]{
R.mipmap.icon_open_red_packet1,
R.mipmap.icon_open_red_packet2,
R.mipmap.icon_open_red_packet3,
R.mipmap.icon_open_red_packet4,
R.mipmap.icon_open_red_packet5,
R.mipmap.icon_open_red_packet6,
R.mipmap.icon_open_red_packet7,
R.mipmap.icon_open_red_packet7,
R.mipmap.icon_open_red_packet8,
R.mipmap.icon_open_red_packet9,
R.mipmap.icon_open_red_packet4,
R.mipmap.icon_open_red_packet10,
R.mipmap.icon_open_red_packet11,
};
每一帧为按钮不同角度的图片
创建FrameAnimation对象
mFrameAnimation = new FrameAnimation(mIvOpen, mImgResIds, 125, true);
mFrameAnimation.setAnimationListener(new FrameAnimation.AnimationListener() {
@Override
public void onAnimationStart() {
Log.i("", "start");
}
@Override
public void onAnimationEnd() {
Log.i("", "end");
}
@Override
public void onAnimationRepeat() {
Log.i("", "repeat");
}
@Override
public void onAnimationPause() {
mIvOpen.setBackgroundResource(R.mipmap.icon_open_red_packet1);
}
});
FrameAnimation中可以设置对执行动画时某些时机的监听。
弹框中按钮的点击监听
@OnClick({R.id.iv_close, R.id.iv_open})
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_close:
stopAnim();
if (mListener != null) {
mListener.onCloseClick();
}
break;
case R.id.iv_open:
if (mFrameAnimation != null) {
//如果正在转动,则直接返回
return;
}
startAnim();
if (mListener != null) {
mListener.onOpenClick();
}
break;
}
}
回调给OnRedPacketDialogClickListener接口,当点击弹框的打开按钮时,如果已经在旋转,则无需再进行旋转。
Activity中弹出红包弹框
public void showDialog(View view){
RedPacketEntity entity = new RedPacketEntity("chaychan", "http://upload.51qianmai.com/20171205180511192.png", "大吉大利,今晚吃鸡");
showRedPacketDialog(entity);
}
public void showRedPacketDialog(RedPacketEntity entity) {
if (mRedPacketDialogView == null) {
mRedPacketDialogView = View.inflate(this, R.layout.dialog_red_packet, null);
mRedPacketViewHolder = new RedPacketViewHolder(this, mRedPacketDialogView);
mRedPacketDialog = new CustomDialog(this, mRedPacketDialogView, R.style.custom_dialog);
mRedPacketDialog.setCancelable(false);
}
mRedPacketViewHolder.setData(entity);
mRedPacketViewHolder.setOnRedPacketDialogClickListener(new OnRedPacketDialogClickListener() {
@Override
public void onCloseClick() {
mRedPacketDialog.dismiss();
}
@Override
public void onOpenClick() {
//领取红包,调用接口
}
});
mRedPacketDialog.show();
}
点击按钮后的相关业务逻辑,可以在onOpenClick()回调中实现。
对FrameAnimation的修改
FrameAnimation 并没有回调动画暂停的监听,我们在打开红包成功或者请求失败(网络异常)时,按钮应暂停旋转,此时需要监听到暂停,在回调中将图片切换为第一帧。
到这里,仿微信红包打开的动画就介绍完了,为了方便大家参考,我将demo代码也上传到github上。