android有非常成熟的动画系统,程序员可以借助anroid的动画系统设计出匹配商业广告的动画。
android从早期的补间动画发展到今天的属性动画,乃至lottie动画和opengl动画。
补间动画效率应该比属性动画高,但缺点是不改变view属性,比如放大或者移动一个view,view的点击区域并不会随之变化,在某些场合下依然是个选择。属性动画会修改view的属性,这在有时是需要的,如果不是必要,尽量使用属性动画,因为他功能更强大,而且支持非view变化,比如我们需要修改view图片的形状,模仿眼睛眨动或者半闭全闭的动态效果,就离不开属性动画,因为我们不是仅需要修改view,还要修改view的内容。

动画的基础知识点非常多,这里不再赘述,一个综合的例子可以学到很多东西。这里不回顾动画的基础知识,直接应用,如果有看不明白的,可以留言。
PropertyValuesHolder让我们可以把一个复杂的动画分解成位移,放缩,修改颜色,形状等子动画,
Keyframe可以让我们精确的控制每一帧的变化,间隔一定时间的相同的帧可以让我们在动画某个时刻停留固定时间,
为特定的关健帧设置setInterpolator可以增强动感,多个PropertyValuesHolder的组合,让我们可以把各种效果合并在一个动画里,便于精确控制,虽然AnimatorSet也能实现这一点,但是当我们需要先位移,到固定位置后再放缩同时修改形状,然后还原形状和大小,最后回到原位,比如模拟一个机器开心的动画, 把复杂的动画拆解再组合成animator,便于我们精确动画每一帧的变化,启动和结束。
void creatSleep(){
final View fv = this.findViewById(R.id.fface);
final View lv = bmcDemoActivity3.this.findViewById(R.id.fleft);
final View rv = bmcDemoActivity3.this.findViewById(R.id.fright);
//Keyframe keyframe = Keyframe.ofInt();
Keyframe keyframe = Keyframe.ofFloat(0,0);
keyframe.setInterpolator(new DecelerateInterpolator());
Keyframe keyframe0 = Keyframe.ofFloat(0.1f,-200); //500ms
Keyframe keyframe1 = Keyframe.ofFloat(0.9f,-200); //4500ms
keyframe.setInterpolator(new AccelerateInterpolator());
Keyframe keyframe2 = Keyframe.ofFloat(1f,0);
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationY",keyframe,keyframe0
,keyframe1,keyframe2);
Keyframe keyframe00 = Keyframe.ofFloat(0,1.0f);
Keyframe keyframe01 = Keyframe.ofFloat(0.1f,1.0f); //500
keyframe01.setInterpolator(new AccelerateInterpolator());
Keyframe keyframe011 = Keyframe.ofFloat(0.2f,1.5f); //1000
Keyframe keyframe02 = Keyframe.ofFloat(0.8f,1.5f); //4000
keyframe02.setInterpolator(new AccelerateInterpolator());
Keyframe keyframe03 = Keyframe.ofFloat(0.9f,1.0f); //4500
Keyframe keyframe04 = Keyframe.ofFloat(1f,1.0f);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofKeyframe("scaleY",keyframe00,keyframe01,keyframe011
,keyframe02,keyframe03, keyframe04);
Keyframe keyframe10 = Keyframe.ofFloat(0,0f);
Keyframe keyframe11 = Keyframe.ofFloat(0.1f,0f); //500
keyframe11.setInterpolator(new AccelerateInterpolator());
Keyframe keyframe12 = Keyframe.ofFloat(0.2f,50f); //1000
Keyframe keyframe122 = Keyframe.ofFloat(0.8f,50f); //4000
keyframe122.setInterpolator(new AccelerateInterpolator());
Keyframe keyframe13 = Keyframe.ofFloat(0.9f,0f); //4500
Keyframe keyframe14 = Keyframe.ofFloat(1f,0.0f);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofKeyframe("test",keyframe10,keyframe11
,keyframe12,keyframe122, keyframe13, keyframe14);
final ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(fv, holder, holder2, holder3);
animator.setDuration(5000);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(@NonNull ValueAnimator animation) {
float scaleYValue = (float) animation.getAnimatedValue("test");
//fv.setScaleX(scaleYValue);
Drawable d = createDrawagle(100-scaleYValue);
lv.setBackground(d);
}
});
animator.start();
}
修改形状可以使用BitmapShader,这是一个功能十分强大的函数,也可以使用setXfermode,这是一个比BitmapShader功能更强大的函数,可以使用他几乎可以得到任意图形,结合数学函数知识,我们可以动态绘制很多神奇的图形,


这是 一个应用setXfermode实现的半闭眼效果,也是上面用到的函数。
Drawable createDrawagle(float value){
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Bitmap bitmap2 = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Paint p = new Paint();
p.setColor(Color.WHITE);
p.setAntiAlias(true);
Canvas c = new Canvas(bitmap);
Canvas c1 = new Canvas(bitmap2);
c.drawCircle(50,50, 50, p);
c1.drawRect(new RectF(0, 0, 100, 100), p);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
//c.drawRect(new RectF(0, (100-value)/2, 100, ((100-value)/2)+value), p);
//c.drawRect(new RectF(0, 0, 100, 50), p);
c.drawBitmap(bitmap2, 0, value, p);
BitmapDrawable drawable = new BitmapDrawable(getResources(), bitmap);
return drawable;
}
330

被折叠的 条评论
为什么被折叠?



