Android--自定义Drawable基础

1、前言

Drawable 在我们的日常开发中是经常使用的,而且非常的有用。能够在canvas上绘制,而且相比于View,并不需要去考虑measure、layout,仅仅只要去考虑如何draw(canavs)。我们在学习和使用 Drawable 的时候,当然不能只了解官方提供给我们的那些传统的用法,我们应该学会自定义实现自己想要的效果。

2、原理

Drawable 的原理我们如果要自定义的话是必须了解的,主要是这个方法:

  • draw(Canvas canvas)

和View一样,我们是在 draw() 里面对 Canvas 画布进行绘制,我们这个画布就是从 Drawable 附着的 View对象那里来的。draw() 是我们唯一的核心方法。

3、CircleDrawable

这个 Drawable 是用来对图片做圆形处理的,将图片的 Bitmap 对象传入,就会得到一个圆形的 Drawable 资源。

public class CircleDrawable extends Drawable {

    private Paint mPaint;
    private int mWidth;
    private Bitmap mBitmap;

    public CircleDrawable(Bitmap bitmap) {
        this.mBitmap = bitmap;
        BitmapShader bitmapShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setShader(bitmapShader);
        mWidth = Math.min(mBitmap.getWidth(), mBitmap.getHeight());
    }

    @Override
    public void draw(Canvas canvas) {
        // TODO Auto-generated method stub
        canvas.drawCircle(mWidth/2, mWidth/2, mWidth/2, mPaint);
    }

    @Override
    public void setAlpha(int alpha) {
        // TODO Auto-generated method stub
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        // TODO Auto-generated method stub
        mPaint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        // TODO Auto-generated method stub
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public int getIntrinsicHeight() {
        // TODO Auto-generated method stub
        return mWidth;
    }

    @Override
    public int getIntrinsicWidth() {
        // TODO Auto-generated method stub
        return mWidth;
    }
}

这个代码是很简单的,因为我们设置的是个圆形,所以宽高是一样的,我们用的是位图,所以需要一个着色器,TitleMode是图片平铺的方式,这个与 BitmapDrawable 是一样的。设置 Paint 属性相信大家都是驾轻就熟啦,重写方法也没什么。draw() 因为我们只是做基础的圆形,所以用用canvas 的 drawCircle() 即可。另外,还有getIntrinsicWidth() 和 getIntrinsicHeight() 虽然不是必须重写的方法,但为了在View使用wrap_content的时候,提供一下尺寸,我们也重写它。我们可以拿它去和其它获得宽高的方法比较:

  • getWidth() 是实际显示的宽度。
  • getMeasureWidth() 是测量宽度,在布局之前计算出来的。
  • getIntrinsicWidth() 是原有宽度,有时候原有宽度可能很大,但是实际上空间不够,所有效果上并没有那么大,这个方法可以获得原有宽度,可以辅助测量的时候选择合适的展示宽度。
  • getMinimumWidth() 是最小宽度,是XML参数定义里的 minWidth,也是一个辅助测量展示的参数。

这个圆形 Drawable 的原有的值当然是我们测量的mWidth。

public class CustomerDrawableActivity extends Activity {

    private ImageView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_customer);
        iv = (ImageView) findViewById(R.id.iv);

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.picture);
        iv.setImageDrawable(new RoundDrawable(bitmap));
    }
}

4、RoundDrawable

这是给图片设置圆角的 Drawable,代码也很简单。

public class RoundDrawable extends Drawable {

    private Paint mPaint;
    private RectF rectF;
    private Bitmap mBitmap;

    public RoundDrawable(Bitmap bitmap) {
        this.mBitmap = bitmap;
        BitmapShader bitmapShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setShader(bitmapShader);
    }

    @Override
    public void draw(Canvas canvas) {
        // TODO Auto-generated method stub
        canvas.drawRoundRect(rectF, 30, 30, mPaint);
    }

    @Override
    public void setBounds(int left, int top, int right, int bottom) {
        rectF = new RectF(left, top, right, bottom);
    }

    @Override
    public void setAlpha(int alpha) {
        // TODO Auto-generated method stub
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        // TODO Auto-generated method stub
        mPaint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        // TODO Auto-generated method stub
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public int getIntrinsicHeight() {
        // TODO Auto-generated method stub
        return mBitmap.getHeight();
    }

    @Override
    public int getIntrinsicWidth() {
        // TODO Auto-generated method stub
        return mBitmap.getWidth();
    }
}

RoundDrawable 与 CircleDrawable 不一样的就是,我们还多了一个 setBounds() 方法,这是给我们 Drawable 提供边界的尺寸,就是绘制的范围。

用法和 CircleDrawable 是一致的。

以上就是自定义Drawable的内容了,这两种Drawable都是比较基础和常用的,如果你想要实现比较复杂的内效果,可以以这个为基础去搭建修改。当然 xml 的效果也足够强大,我们在开发的时候可不能忘掉它哦。

结束语:本文仅用来学习记录,参考查阅。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值