Android 自定义Drawable

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.setXfermode(pdf);
        paint.setColor(0xffff4400);
        canvas.drawBitmap(bmp, 0, 0, paint);
        paint.setXfermode(null);
    }

》》XferMode

  1. AvoidXfermode  指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。
  2. PixelXorXfermode  当覆盖已有的颜色时,应用一个简单的像素异或操作。
  3. PorterDuffXfermode  这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-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

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#ff80cbc4" />
        </shape>
    </item>
    <item android:top="48dp">
        <bitmap
            android:gravity="center"
            android:src="@drawable/app_background_png"
            android:tileMode="disabled" />
    </item>
</layer-list>

6.自定义按钮状态

    <declare-styleable name="CustomStateDrawableButton">
        <attr name="state_readed" format="boolean" />
    </declare-styleable>

定义一个状态

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
时间: 2024-10-08 10:13:19

Android 自定义Drawable的相关文章

Android 自定义Drawable 资源引用问题

问题的复现: Activity布局文件代码如下: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_par

android自定义样式大全:shape,selector,layer-list,drawable,动画,style

原文:http://keeganlee.me/post/android/20150830 以下摘取了部分内容: shape 一般用shape定义的xml文件存放在drawable目录下,若项目没有该目录则新建一个,而不要将它放到drawable-hdpi等目录中.只需要在对应控件设置(bg_rectangle_with_stroke_dash.xml) android:background="@drawable/bg_rectangle_with_stroke_dash" 四种类型 使

Android中的Drawable菠菜bc网站搭建架设基础与自定义Drawable

6.gravity属性详情 可选项 含义top/bottom/left/right 将图片放在容器上/下/左/右,不改变图片大小center_vertical/horizontal 垂直居中/水平居中,不改变图片大小center 水平和垂直方向同时居中,不改变图片大小fill_vertical/horizontal 垂直/水平方向填充容器fill 水平和垂直方向同时填充容器clip_vertical/horizontal 垂直/水平方向的裁剪-较少使用7.NinePatchDrawable(.9

Android 应用开发中如何自定义 Drawable 背景?

2020-02-06 关键字:EditText自定义背景.shape.corners 通过 xml 定义 View 的背景 Drawable 资源还是挺常用的. 本篇博文记录几种常用的自定义 Drawable 方式. 1.圆角矩形 A.普通圆角矩形 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/

Android自定义“图片+文字”控件四种实现方法之 二--------个人最推荐的一种

http://blog.csdn.net/yanzi1225627/article/details/8633872 第二种方法也要新建一个图片+文字的xml布局文件,然后写一个类继承自LinearLayout.在主程序里实例化并设置相应参数.这种方式也是我最推荐的一种. 第一部分:myimgbtn_layout.xml [html] view plaincopyprint? <?xml version="1.0" encoding="utf-8"?> &

Android 自定义ProgressDialog示例实现

闲来无事,总结了两个自定义的ProgressDialog,大家可以参考下,根据自己需要进行选择修改: 实现效果: 示例1: 示例2: 代码如下: MainActivity:只是两个Button点击事件 package com.customwaitdialog; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import

Android:自定义DialogFragment的内容和按钮

小问题,记录下~ Android4.0以后开始推荐使用DialogFragment代替Dialog.Android的官方文档中给了两个示例: 一个Basic Dialog 示例了如何自定义窗口内容--重写onCreateView方法. 一个Alert Dialog 示例了如何自定义弹窗的正负按钮--重写onCreateDialog方法. 好的,那么问题来了 在实际应用中经常是需要既自定义窗口内容.又需要自定义按钮的. 这时候如果我们按图索骥,把DialogFragment的onCreateVie

android 自定义权限

理解android的自定义权限,下面介绍一段代码.包括两个安卓项目,project 2试图调用project 1中的特权活动PrivActivity. android project 1 : application name: Custom Permission pacakage name: com.cust.perm 1) 特权活动 PrivActivity.java package com.cust.perm; import android.app.Activity; import andr

Android自定义可循环的滚动选择器CycleWheelView 替代TimePicker/NumberPicker/WheelView

最近碰到个项目要使用到滚动选择器,原生的NumberPicker可定制性太差,不大符合UI要求. 网上开源的WheelView是用ScrollView写的,不能循环滚动,而且当数据量很大时要加载的Item太多,性能非常低. 然后,还是自己写一个比较靠谱,用的是ListView实现的.写完自己体验了一下,性能不错,再大的数据也不怕了. 感觉不错,重新封装了一下,提供了一些接口可以直接按照自己的需求定制,调用方法在MainActivity中. 不多说了,直接上代码: CycleWheelView.j