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,用来绘制图片。