Android中的Drawable和动画

作者: 斜杠时光 | 来源:发表于2017-03-24 23:03 被阅读286次

    Android中Drawable是一种可以在Canvas上进行绘制抽象的概念,种类很多,常见的颜色和图片都可以是一个Drawable。Drawable有很多种,它们表示一种图像的概念,但是它们又不全是图片,通过颜色也可以构造出各式各样的图像的效果。

    Drawable的分类

    • BitmapDrawable。它表示的就是一张图片,在实际开发中我们可以直接引用原始的图片即可。
    • ShapeDrawable。可以理解为通过颜色来构造图形,可以有纯色的图形,也可以具有渐变效果的图形。
    • LayerDrawable。对应的标签是<Layer-list>,它表示一种层次化的Drawable集合,通过将不同的Drawable放置在不同的层上面从而达到一种叠加后的效果。
    • StateListDrawable。对应于<Selector>,它表示Drawable集合,每个Drawable都对应着View的一种状态,这样系统就会根据View的状态来选择合适的Drawable。
    • LeveListDrawable。对应于<level-list>标签,表示一个Drawable集合,集合中的每个Drawable都有一个等级Level的概念。
    • InsetDrawable。对应于<insert>标签,它可以将其他的Drawable内嵌到自己当中,并可以在四周留出一定的间距。
    • ScaleDrawable。对应于<scale>,它可以根据自己的等级(level)将指定的Drawable缩放到一定比例。
    • ClipDrawable。对应于<clip>,它可以根据自己当前的等级(level)来裁剪另一个Drawable,裁剪方向可以通过android:clipOrientation和android:gravity这两个属性来共同控制。

    Android动画

    Android的动画可以分为三种:View动画、帧动画和属性动画。View动画通过对场景里的对象不断做图像变换(平移、缩放、旋转、透明度)从而产生动画效果,它是一种渐近式动画,并且View动画支持自定义。帧动画通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画。属性动画通过动态地改变对象的属性从而达到动画效果,属性动画为API 11的新特性,在低版本无法直接使用属性动画,但我们仍然可以通过兼容库来使用它。

    View动画

    View动画的作用对象是View,它支持平移动画、缩放动画、旋转动画和透明度动画。有四个子类:TranslateAnimation,ScaleAnimation,RotateAnimation和AlphaAnimation。可以通过XML来定义。比如:

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="300"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:shareInterpolator="true" >
    
        <alpha
            android:fromAlpha="0.0"
            android:toAlpha="1.0" />
    
        <translate
            android:fromYDelta="500"
            android:toXDelta="0" />
    
    </set>
    

    帧动画

    帧动画是顺序播放一组预先定义好的图片,类似于电影播放。不同于View动画,系统提供了另外一个类AnimationDrawable来使用帧动画。虽然比较简单,但是容易引起OOM,所以在使用帧动画时应尽量避免使用过多尺寸较大的图片。

    属性动画

    属性动画中有ValueAnimator、ObjectAnimator和AnimatorSet等概念,通过它们可以实现绚丽的动画。属性动画可以对任意对象的属性进行动画而不仅仅是View,动画默认时间间隔300ms,默认帧率10ms/帧。在一个时间间隔内完成对象从一个属性值到另一个属性值的改变,因此属性动画几乎是无所不能,只要对象有这个属性,它都能实现动画效果。

    有个开源动画库:nineoldandroids来兼容之前的版本,因为属性动画是从API 11开始才有的。比较常用的动画类ValueAnimator、ObjectAnimator和AnimatorSet,其中ObjectAnimator继承ValueAnimator,AnimatorSet是动画集合,可以定义一组动画,它们使用起来也是极其简单的。如何使用呢:

     private void performAnimate(final View target, final int start, final int end) {
            ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
            valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
    
                // 持有一个IntEvaluator对象,方便下面估值的时候使用
                private IntEvaluator mEvaluator = new IntEvaluator();
    
                @Override
                public void onAnimationUpdate(ValueAnimator animator) {
                    // 获得当前动画的进度值,整型,1-100之间
                    int currentValue = (Integer) animator.getAnimatedValue();
                    Log.d(TAG, "current value: " + currentValue);
    
                    // 获得当前进度占整个动画过程的比例,浮点型,0-1之间
                    float fraction = animator.getAnimatedFraction();
                    // 直接调用整型估值器通过比例计算出宽度,然后再设给Button
                    target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);
                    target.requestLayout();
                }
            });
    
            valueAnimator.setDuration(5000).start();
        }
    

    使用动画注意点

    • OOM问题。这个主要是出现在帧动画中,当图片数量较多且图片较大时就极易出现OOM。
    • 内存泄漏。在属性动画中有一类无限循环的动画,这类动画需要在Activity退出时及时停止,否则将导致Activity无法释放从而造成内存泄漏,View动画则并不存在此问题。
    • 兼容性问题。动画在3.0以下的系统上有兼容性问题,在某些特殊场景可能无法正常工作,因此要做好适配问题。
    • View动画的问题。View动画是对View的影像做动画,并不是真正改变View的状态,因此有时候会出现动画完成后View无法隐藏的现象,即setVisibility(View.GONE)失效了,这个时候只要调用View.clearAnimation()清除View动画即可解决此问题。
    • 不要使用PX。在进行动画的过程中,要尽量使用dp,使用px会导致在不同设备上有不同的效果。
    • 动画元素的交互。将View移动(平移)后,在Android 3.0以前的系统上,不管是View动画还是属性动画,新位置均无法触发单击事件,同时,老位置仍然可以触发单击事件。尽管View已经在视觉上不存在了,将View移回原位置以后,原位置的单击事件继续生效。从3.0开始,属性动画的单击事件触发位置为移动后的位置,但是View动画仍然在原位置。
    • 硬件加速。使用动画过程中,建议开启硬件加速,这样会提高动画的流畅性。

    相关文章

      网友评论

        本文标题:Android中的Drawable和动画

        本文链接:https://www.haomeiwen.com/subject/aceqottx.html