Android UI:动画:帧动画

定义

按顺序展示不同的图片

API

AnimationDrawable

是Drawabe的子孙类 ,AnimationDrawable继承DrawableContainer, DrawableContainer继承Drawable       

XML文件

R.drawable.XXX
标签:animation-list

操作

作为Drawable,直接显示在View或ImageView上

View对象.setBackground(R.drawable.xxx)
View对象.setBackground(Drawable)
ImageView对象setImageDrawable(Drawable)


创建AnimationDrawable对象

(AnimationDrawable)Context对象.getResources().getDrawable(R.drawable.xxx)

启动动画

AnimationDrawable对象.start()
//不能在Activity的onCreate方法中调用,因为此时AnimationDrawable还未完全附着到window上,最好的调运时机是在onWindowFocusChanged()方法中    

停止动画

AnimationDrawable对象.stop()

判断动画是否在运行

AnimationDrawable对象.isRunning()

源码分析

View和Drawable:委托模式

委托模式:Drawable调用View中的方法

View依赖Drawable

Drawable中定义Callback接口,持有一个Callback对象,并调用Callback的方法

View实现Callback接口

在View.setBackground或Image.setImageDrawable中,将View作为Callback注入到Drawable中,Drawable调用View中的方法

源码
Drawable和Drawable.Callback
class Drawable {

    public interface Callback {
        void invalidateDrawable(@NonNull Drawable who);
        void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when);
        void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what);
    }


    private WeakReference<Callback> mCallback = null;

    public final void setCallback(@Nullable Callback cb) {
        mCallback = cb != null ? new WeakReference<>(cb) : null;
    }

    public void invalidateSelf() {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.invalidateDrawable(this);
        }
    }

    public void scheduleSelf(@NonNull Runnable what, long when) {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.scheduleDrawable(this, what, when);
        }
    } 

    public void unscheduleSelf(@NonNull Runnable what) {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.unscheduleDrawable(this, what);
        }
    }
}
View
class View implements Drawable.Callback ... {

    @Override
    public void invalidateDrawable(@NonNull Drawable drawable) {
        ... ...
    }

    @Override
    public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
       ... ...
    }
    @Override
    public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
       ... ...
    }
}

DrawableContainer和Drawable

DrawableContainer:封装一组Drawable
1.实现Drawable.Callback接口,实际上是调用View的同名方法

2.封装一个Drawable[]数组和两个Drawable对象(mCurrentDrawable、mLastDrawable)

Drawable[]数组封装在静态内部类DrawableContainerState

每次向Drawable[]数组中添加Drawable,Drawable的Callback设置为DrawableContainer本身

3.继承Drawable对象,重写draw(Canvas)方法,画mCurrentDrawable或mLastDrawable
小结

Drawable的Callback对象是DrawableContainer
DrawableContainer的Callback对象是View

AnimationDrawable和View

AniationDrawable
继承DrawableContainer,封装一组Drawable
实现Runnable接口

作为一个Runnable完成延迟显示下一个Drawable的任务

1.显示当前Drawable
2.设置Drawable数组中的下一个Drawable为当前Drawable
3.将AnimationDrawable自身作为Runnable和间隔时间,通过Callback传递给View

View

利用Handler延迟执行传入的Runnable,即AnimationDrawable 

AnimationDrawable.start

将AnimationDrawable自身作为Runnable和间隔时间,通过Callback传递给View

总结

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值