上篇文章中,我们创建了礼物动画类,其中的功能为:
1、添加礼物
2、 添加礼物布局类,
3、显示礼物布局
礼物布局,它的作用为:
1、创建布局后显示其中的数据
今天的文章主要是完善上面的类的功能:
1、暴击
2、无限数据添加
3、礼物面板被顶上去之后,在暴击时间内需要重新回到暴击面板中
在前一篇文章中,GiftControl
类中,添加礼物后,开始了一个进入礼物面板的动画:
public AnimatorSet startAnimation(IBaseAnim anim) {
this.anim = anim;
hideView();
//布局飞入
ObjectAnimator flyFromLtoR = LiveGiftAnimationUtil.createFlyFromLtoR(mGiftItemContent, -getWidth(), 0, 400L, new OvershootInterpolator());
flyFromLtoR.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
}
});
//礼物飞入
ObjectAnimator flyFromLtoR2 = LiveGiftAnimationUtil.createFlyFromLtoR(mIvGift, -getWidth(), 0, 500L, new DecelerateInterpolator());
flyFromLtoR2.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mIvGift.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
comboAnimation(true);
}
});
return LiveGiftAnimationUtil.startAnimation(flyFromLtoR, flyFromLtoR2);
}
从这里开始,动画结束后,就有一个暴击倒计时,这个我们有多种实现方式,这里我们使用Handler
实现:
private Handler mHandler = new Handler(this); // 连击hander
private Runnable mCurrentAnimRunnable; // 连击检测runnable
/**
* 连击结束时回调
*/
public void comboEndAnim() {
if (mHandler != null) {
if (mCurrentAnimRunnable == null) {
mCurrentAnimRunnable = new GiftNumAnimaRunnable();
mHandler.postDelayed(mCurrentAnimRunnable, GIFT_DISMISS_TIME);
}
}
}
// 动画连接runnable
private class GiftNumAnimaRunnable implements Runnable {
@Override
public void run() {
dismissGiftLayout();
}
}
上面,当连击结束之后,就使用Handler
开始postDelayed
一个延时的方法来显示礼物消息。在这期间,如果有新的礼物进来,就判断当前是否在显示,所以需要在GiftControl
的loadGift()
方法中完善:
// 保存礼物view
private LinkedList<LiveGiftLayout> mLiveGiftLayouts;
/**
* 加入礼物,具有实时连击效果
*
* @param gift
* @param supportCombo 是否支持实时连击,如果为true:支持,否则不支持
*/
public synchronized void loadGift(LiveGiftBean gift, boolean supportCombo,
boolean isFirst) {
Iterator<LiveGiftLayout> liveGiftLayoutIterator
= mLiveGiftLayouts.iterator();
while (liveGiftLayoutIterator.hasNext()) {
// 获取到队列中的view
LiveGiftLayout giftLayout = liveGiftLayoutIterator.next();
// 判断是否在之前存在
if (giftLayout.getCurrentGiftId().equals(gift.getGiftId()) &&
giftLayout.getCurrentSendUserId().equals(gift.getSendUserId())) {
if (giftLayout.isRemove()) {
// 去掉 消失的回调 整条数据是没用的了
giftLayout.removeDismissGiftCallback();
// 被顶出去了
liveGiftLayoutIterator.remove();
gift.setGiftCount(giftLayout.getGiftCount() + 1);
showGift(gift);
} else {
//连击
giftLayout.updateGiftCount(gift.getGiftCount());
giftLayout.setSendGiftTime(gift.getSendGiftTime());
}
return;
}
}
showGift(gift);
}
}
上面的注释,首先,我们需要有一个 mLiveGiftLayouts
变量来保存所有添加进的的layout
,添加进来之后,在下一次加入新的数据就遍历其中所有的数据,然后来判断是否可以暴击,如果是暴击的话,就把数量给累加进入然后重新设置值;
在暴击的时候,需要移除掉handler
的GiftNumAnimaRunnable
,不然在GIFT_DISMISS_TIME
之后,就会自动移除,所以每次暴击开始就要移除掉消失的runnable
,在暴击动画(数组变大的动画)结束后,重新开始倒计时!
/**
* 增加礼物数量,用于连击效果
*
* @param count
*/
public synchronized void setGiftCount(int count) {
mGiftCount += count;
mGift.setGiftCount(mGiftCount);
++mCombo;
mTvGiftNum.setText("x " + (mCombo));
comboAnimation(false);
removeDismissGiftCallback();
}
public void comboAnimation(boolean isFirst) {
if (isFirst) {
mTvGiftNum.setVisibility(View.VISIBLE);
mTvGiftNum.setText("x " + mCombo);
Log.d(TAG, "comboAnimation 连击:" + mCombo);
comboEndAnim();
} else {
//数量增加
ObjectAnimator scaleGiftNum = LiveGiftAnimationUtil.scaleGiftNum(mTvGiftNum);
scaleGiftNum.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
comboEndAnim();
}
});
scaleGiftNum.start();
}
}
不是第一次就走了下面的逻辑,数字变大的动画结束之后,回调到了暴击动画结束的方法;
到此,主要的逻辑就写完了,还是很简单的。
代码上传到了https://github.com/shejishi/ComboGift喜欢的给个Star❤~
网友评论