博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 自定义Drawable
阅读量:6496 次
发布时间:2019-06-24

本文共 4788 字,大约阅读时间需要 15 分钟。

1.使用BitmapShader实现图片圆角

public class CornerDrawable extends Drawable {    private Paint mPaint;    private Bitmap bmp;    private RectF rectF;    public CornerDrawable(Bitmap bmp) {        this.bmp = bmp;        BitmapShader shader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);//        CLAMP 拉伸//        REPEAT 重复//        MIRROR 镜像//        BitmapShader是从画布的左上角开始绘制的        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setShader(shader);    }    @Override    public void draw(Canvas canvas) {        Rect rect = getBounds();        // Log.e(getClass().getSimpleName(), rect.left + ":" + rect.width() + ":" + rect.height());        // Log.e(getClass().getSimpleName(), rectF.left + ":" + rectF.width() + ":" + rectF.height());        canvas.drawRoundRect(rectF, 20, 20, mPaint);    }    @Override    public void setAlpha(int alpha) {        mPaint.setAlpha(alpha);    }    @Override    public void setColorFilter(ColorFilter cf) {        mPaint.setColorFilter(cf);    }    @Override    public int getOpacity() {        return PixelFormat.TRANSLUCENT;    }    // getIntrinsicWidth、getIntrinsicHeight主要是为了在View使用wrap_content的时候,提供一下尺寸    @Override    public int getIntrinsicHeight() {        return bmp.getHeight();    }    @Override    public int getIntrinsicWidth() {        return bmp.getWidth();    }    @Override    public void setBounds(int left, int top, int right, int bottom) {        super.setBounds(left, top, right, bottom);        rectF = new RectF(left, top, right, bottom);    }}

2.除了圆角外,还可以指定画图片的某圆弧对应的内容

重写上面的draw方法如下

RectF rf = new RectF(-100, -130, 160, 130);canvas.drawArc(rf, 0, 120, true, paint);

3.使用PorterDuffXfermode

@Override    public void draw(Canvas canvas) {        PorterDuffXfermode pdf = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);      paint.drawBitmap(dst, 0, 0, paint);        paint.setXfermode(pdf);        paint.setColor(0xffff4400);        canvas.drawBitmap(src, 0, 0, paint);        paint.setXfermode(null);    }

http://www.jianshu.com/p/d11892bbe055

》》XferMode

  1. AvoidXfermode  指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)
  2. PixelXorXfermode  当覆盖已有的颜色时,应用一个简单的像素异或操作。
  3. PorterDuffXfermode  这是一个非常强大的转换模式,使用它,可以使用图像合成的16Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。

》》PorterDuff.Mode为枚举类,一共有16个枚举值:

  • PorterDuff.Mode.CLEAR    所绘制不会提交到画布上。
  • PorterDuff.Mode.SRC   显示上层绘制图片
  • PorterDuff.Mode.DST  显示下层绘制图片
  • PorterDuff.Mode.SRC_OVER  正常绘制显示,上下层绘制叠盖。
  • PorterDuff.Mode.DST_OVER  上下层都显示。下层居上显示。
  • PorterDuff.Mode.SRC_IN   取两层绘制交集。显示上层。
  • PorterDuff.Mode.DST_IN  取两层绘制交集。显示下层。
  • PorterDuff.Mode.SRC_OUT 取上层绘制非交集部分。
  • PorterDuff.Mode.DST_OUT 取下层绘制非交集部分。
  • PorterDuff.Mode.SRC_ATOP 取下层非交集部分与上层交集部分
  • PorterDuff.Mode.DST_ATOP 取上层非交集部分与下层交集部分
  • PorterDuff.Mode.XOR  异或:去除两图层交集部分
  • PorterDuff.Mode.DARKEN  取两图层全部区域,交集部分颜色加深
  • PorterDuff.Mode.LIGHTEN  取两图层全部,点亮交集部分颜色
  • PorterDuff.Mode.MULTIPLY  取两图层交集部分叠加后颜色
  • PorterDuff.Mode.SCREEN  取两图层全部区域,交集部分变为透明色

参考:ApiDemos/Graphics/XferModes

 4.对图片进行颜色转换

public static Drawable getPrimaryDrawable(int resId) {        Drawable icon = context.getResources().getDrawable(resId);        int baseColor = context.getResources().getColor(R.color._secondary_color);        icon.setColorFilter(baseColor, PorterDuff.Mode.SRC_IN);        return icon;    }

5.通过xml定义drawable

6.自定义按钮状态

定义一个状态

public class CustomStateDrawableButton extends ImageButton {    public static final int[] MessageReaded = {R.attr.state_readed};    private boolean isReaded = false;    public CustomStateDrawableButton(Context context) {        super(context);    }    public CustomStateDrawableButton(Context context, AttributeSet attrs) {        super(context, attrs);    }    public CustomStateDrawableButton(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    public void setReaded(boolean isReaded) {        if (this.isReaded != isReaded) {            this.isReaded = isReaded;            //            refreshDrawableState();        }    }    @Override    public int[] onCreateDrawableState(int extraSpace) {        if (!isReaded) {            int[] ds = super.onCreateDrawableState(extraSpace + 1);            mergeDrawableStates(ds, MessageReaded);            return ds;        }        return super.onCreateDrawableState(extraSpace);    }}
// http://www.devdiv.com/Android-Android%E4%B8%ADDrawable%E5%88%86%E7%B1%BB%E6%B1%87%E6%80%BB%EF%BC%88%E4%B8%8A%EF%BC%89-thread-126853-1-1.html // ColorDrawable、GradientDrawable、BitmapDrawable、 NinePatchDrawable、InsetDrawable、ClipDrawable、ScaleDrawable、RotateDrawable、AnimationDrawable、LayerDrawable、LevelListDrawable、StateListDrawable、TransitionDrawable

转载于:https://www.cnblogs.com/a284628487/p/5204170.html

你可能感兴趣的文章
最长回文子序列-----动态规划
查看>>
Vue国际化实现
查看>>
设计模式:单例模式
查看>>
FLASH位宽为8、16、32时,CPU与外设之间地址线的连接方法
查看>>
双网卡一般情况不能有两个网关 (转)
查看>>
xshell 远程连接Linux
查看>>
Linux计划任务及压缩归档(week2_day1)--技术流ken
查看>>
ccf算法模板
查看>>
微信小程序登录 该死的官方文档TypeError: the JSON object must be str, not 'bytes'
查看>>
VMware 虚拟机克隆 CentOS 6.5 之后,网络配置问题的解决方案
查看>>
Python ( 1 ) ----- 简介
查看>>
[linux基础学习]run level
查看>>
第七周学习总结
查看>>
一步步的教你安装UChome (UChome 安装教程)
查看>>
[DeeplearningAI笔记]序列模型1.5-1.6不同类型的循环神经网络/语言模型与序列生成...
查看>>
P2533 [AHOI2012]信号塔
查看>>
Android电话拨号器(uri格式)与四种设置点击事件的方法
查看>>
java web中对json的使用
查看>>
TYVJ P1051 选课 Label:多叉转二叉&&树形dp(虐心♥)
查看>>
将数据库中提取出来的数据在后台进行分页处理
查看>>