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
- AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。
- PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素异或操作。
- 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