Drawable

1. Canvas 是爹

首先,要认清一个事实:画布是爹。

无论是画背景,画内容,画滚动条,都是靠爹来完成的。


2. Drawable 

Drawable 比 View 更轻量级,它只是 View 绘制中过程被调用的一个东西(背景,前景)。

自定义 View 的时候,如果只要改变背景的话,最好不要去重写 draw 函数,Drawable 这个类已经被抽象出来负责背景的绘制了。


学习 Drawable 时候,可以尝试从设计意图上去理解。

一方面,它为什么这么设计,子类与父类是如何协作的。

另一方面,Drawable 和 View 和 消息机制等是如何协作的。


3. Drawable 的通性

Drawable 有许许多多的子类,但最复杂的还是 Drawable 本身,作为爹的它要考虑到方方面面。


3.1 setBounds

最基本的形状是什么,是矩形。

无论 Drawable 最终呈现在画布上是什么形状的,它总是被限定在一个矩形当中。

 void setBackgroundBounds() {
        if (mBackgroundSizeChanged && mBackground != null) {
            mBackground.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
            mBackgroundSizeChanged = false;
            rebuildOutline();
        }
    }
在绘制背景时,会将 View 的坐标转换为 bounds,所以 Drawable 都会被拉伸至 View 的大小。
 canvas.drawRect(getBounds(), mPaint);

3.2 setCallBack

首先得看看 Calback 这个接口。

 public static interface Callback {
        public void invalidateDrawable(Drawable who);

        public void scheduleDrawable(Drawable who, Runnable what, long when);

        public void unscheduleDrawable(Drawable who, Runnable what);
    }
View 在设置背景时,drawable 会把 callback 指向 View:

background.setCallback(this);

Drawable 在需要重绘时,会调用:

   public void invalidateSelf() {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.invalidateDrawable(this);
        }
    }
   @Override
    public void invalidateDrawable(@NonNull Drawable drawable) {
        if (verifyDrawable(drawable)) {
            final Rect dirty = drawable.getDirtyBounds();
            final int scrollX = mScrollX;
            final int scrollY = mScrollY;

            invalidate(dirty.left + scrollX, dirty.top + scrollY,
                    dirty.right + scrollX, dirty.bottom + scrollY);
            rebuildOutline();
        }
    }
这一步说明了,Drawable 是 View 附属,它不会仅仅重画自己。


scheduleSelf 是定时重绘自己的意思,就是动画的意思。

unscheduleSelf 则是取消上一步动画的意思,很多时候我们需要让动画戛然而止。


3.3 setState

View 有很多 State,比较常见的是 EditText 的 foucs,以及 Button 的 press。

Drawable 是否根据 View 的状态改变而做出相应的变化,就被称为 isStateful。

触发过程如下:

view.refreshDrawableState -> view.drawableStateChanged -> bg.setState -> bg.onStateChanged


3.4 setLevel

概念上和 setState 差不多,只不过,level 是 drawable 内部使用的。


4. 官网的文章

http://android.xsoftlab.net/guide/topics/resources/drawable-resource.html

http://android.xsoftlab.net/guide/topics/graphics/2d-graphics.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值