zoukankan      html  css  js  c++  java
  • 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.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

    <?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
  • 相关阅读:
    几种回文算法的比较
    算法与数据结构(五)树表的查找
    算法与数据结构(四)利用哈夫曼树编码解码
    算法与数据结构(三)线性表的查找算法
    主存和cache的地址映射
    算法与数据结构(二)三元组矩阵行列式的计算(用递归)
    算法与数据结构(一)将一个数组中的各节点按照层次遍历插入构成完全二叉树
    服务器被攻击,我真是个人才。
    想学嘛,不想学? 自学是门手艺
    想学嘛,技术人, 请不要封闭自己
  • 原文地址:https://www.cnblogs.com/a284628487/p/5204170.html
Copyright © 2011-2022 走看看