Android中通过反射实现圆角ImageView代码实例
privatevoidinit(){
paint=newPaint(Paint.ANTI_ALIAS_FLAG);
roundRect=newRectF(0,0,getWidth(),getHeight());
radius=40;
mPorterDuffXfermode=newPorterDuffXfermode(PorterDuff.Mode.SRC_IN);
}
继承ImageView,在构造方法中调用,初始化Paint和Xfermode。
protectedvoidonDraw(Canvascanvas){
intsc=canvas.saveLayer(0,0,getWidth(),getHeight(),null,
Canvas.MATRIX_SAVE_FLAG|
Canvas.CLIP_SAVE_FLAG|
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG|
Canvas.FULL_COLOR_LAYER_SAVE_FLAG|
Canvas.CLIP_TO_LAYER_SAVE_FLAG);
roundRect.set(0,0,getWidth(),getHeight());
canvas.drawRoundRect(roundRect,radius,radius,paint);
reflectSetXfermod();
super.onDraw(canvas);
canvas.restoreToCount(sc);
}
重写ImageView的onDraw方法,通过xfermode实现圆角
privatevoidreflectSetXfermod(){
Drawabledrawable=getDrawable();
if(drawable==null){
return;
}
ClassbsClass=null;
Class[]innerClasses=BitmapDrawable.class.getDeclaredClasses();
for(ClassinnerClass:innerClasses)
{
Stringname=innerClass.getName();
System.out.println("-----innerClass---"+name);
if(name.equals("android.graphics.drawable.BitmapDrawable$BitmapState"))
{
bsClass=innerClass;
}
}
if(bsClass!=null){
try{
FieldmPaintField=bsClass.getDeclaredField("mPaint");
mPaintField.setAccessible(true);
ConstantStateconstantState=((BitmapDrawable)drawable).getConstantState();
Paintpaint=(Paint)mPaintField.get(constantState);
paint.setXfermode(mPorterDuffXfermode);
}catch(IllegalArgumentExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IllegalAccessExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(NoSuchFieldExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
通过反射的方法将xfermode设置到BitmapDrawable里面的内部类BitmapState里的对象mPaint,用来绘制图片。