本文重在思路和功能,就不介绍自定义view和handler避免内存走漏或是导致空指针这些了,喜爱请clone项目并star、fork一下,感谢各位。
APP需求做一个相似蚂蚁森林的功能模块,动效和蚂蚁森林挨近,水滴最多6滴,依据经向来说这种交互必定用RN、H5亦或游戏引擎来做最佳,可是没办法产品提了咱们也得做。
剖析

正题
解说
创立view最重要的两件作业: 1、给view一个随机的方向而且保存到view的tag里 //随机设置view动画的方向 view.setTag(R.string.isUp, mRandom.nextBoolean()); 2、随机设置view的方位(我这儿并非彻底随机,而是给了一些值,然后随机挑选这些值)、这儿用了一个新的调集保存现已挑选到的数,下次挑选的时分扫除这些值,由于最好水滴不要彻底重合嘛。 /**可是其实这不是我终究的办法,先往下看吧,还有彩蛋**/ /**
* 获取x轴或是y轴上的随机值
*
* @return
*/ private double getX_YRandom(ListchoseRandoms,ListsaveRandoms) { float random = 0; while (random == 0 || saveRandoms.contains(random)) {
random = choseRandoms.get(mRandom.nextInt(choseRandoms.size()));
}
saveRandoms.add(random); return random;
}
/**操控水滴动画的快慢*/ private ListmSpds = Arrays.asList(0.5f, 0.3f, 0.2f, 0.1f); /**
* 设置一切子view的加速度
*/ private void setViewsSpd() { for (int i = 0; i < mViews.size(); i++) {
View view = mViews.get(i);
setSpd(view);
}
} /**
* 设置View的spd
* @param view
*/ private void setSpd(View view) { float spd = mSpds.get(mRandom.nextInt(mSpds.size())); //将这个随机的位移速度保存到view的tag里,这儿两个参数setTag()办法不大了解的能够百度一下 view.setTag(R.string.spd, spd);
}
/**
* 动画移除view
* @param view
*/ private void animRemoveView(final View view) { final float x = view.getX(); final float y = view.getY(); //核算直线间隔 float space = getDistance(new Point((int) x, (int) y), mDestroyPoint);
ValueAnimator animator = ValueAnimator.ofFloat(x, 0); //依据间隔核算动画执行时间 animator.setDuration((long) (REMOVE_DELAY_MILLIS / mMaxSpace * space));
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { if (isCancelAnimtion) { return;
} float value = (float) valueAnimator.getAnimatedValue(); float alpha = value / x; float translationY = y + (x - value) * (maxY - y) / x;
setViewProperty(view, alpha, translationY, value);
}
});
animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { //结束时从容器移除水滴 removeView(view);
}
});
animator.start();
} /**
* 设置view的特点
* @param view
* @param alpha
* @param translationY
* @param translationX
*/ private void setViewProperty(View view, float alpha, float translationY, float translationX) {
view.setTranslationY(translationY);
view.setTranslationX(translationX);
view.setAlpha(alpha);
view.setScaleY(alpha);
view.setScaleX(alpha);
}
-
-
首要创立view
-
接下来为view设置一个初始的随机加速度(其实也是随机在已有的值中选取,由于速度不能相差太大)
-
接下来水滴点击后的消失动画
很明显private double getX_YRandom(ListchoseRandoms, ListsaveRandoms)这个办法走了太屡次,原因就在于我是循环创立view,而且在这个循环内为view随机创立方位,可是为了不彻底重合,我这儿又一次循环知道是一个不同的值停止,也便是说这儿两层循环了
/** * 设置水滴 * @param waters */ public void setWaters(final Listwaters) { if (waters == null || waters.isEmpty()) { return; } //保证初始化完结 post(new Runnable() { @Override public void run() { setDatas(waters); } }); }
喜爱就赞一个吧,你的赞便是我的动力
-
到这儿动效就完了,运转就能抵达想要的姿态了,可是我的作业并没完,翻开profiler一看OMG,在初始化view的当地内存剧增,数量稍稍多一点(10个)还会卡主,看来还的优化啊
-
-
趁便提一下有或许咱们在创立水滴时,父容器还未初始化完结,处理如下
-
-