Reprint please indicate source: http://blog.csdn.net/lmj623565791/article/details/24555655
Originally wanted to find a round corner of the online sample to see a look, disappointments ah, the basic is the official demo of the schematic diagram. will be posted later.
So you define a view for yourself, to achieve the rounded corners of the picture and the round effect. :
The first one is the original, and the second one is the round effect. The third fourth sets a different fillet size.
Ready to change the style of a blog, first of all to tell you the principle, let everyone clear, and then paste the code, otherwise you can directly see that long code is also more painful. The core code is actually just a few lines:
Core Code Analysis:
/** * Draw circular picture based on original and variable length * * @param source * @param min * @return */private Bitmap createcircleimage (Bitmap source, int min {Final Paint paint = new paint ();p Aint.setantialias (true); Bitmap target = bitmap.createbitmap (min, Min, config.argb_8888);/** * Produces a canvas of the same size */canvas canvas = new canvas (target);/** * First Draw round */canvas.drawcircle (MIN/2, MIN/2, MIN/2, paint);/** * Use src_in */paint.setxfermode (new Porterduffxfermode ( PorterDuff.Mode.SRC_IN));/** * Draw picture */canvas.drawbitmap (source, 0, 0, paint); return target;}
In fact, mainly by: Paint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.SRC_IN)); This line of code, for what, I explain to you, src_in such a pattern, Two draw the effect overlay after the intersection to show the figure, how to say, we first draw is a circle, the second draw is a bitmap, so the intersection of the circle, showing the bitmap, the realization of the circular picture effect.
Rounded corners, in fact, is the first to draw a rounded rectangle, is not very easy, later people say the realization of rounded corners. You just give him this line of code.
From the demo sample of Android, let's prove it:
Here's a porterduff.mode of 16, and we're just one of the two:
Source code We only care who first who is drawn after:
Canvas.translate (x, y); Canvas.drawbitmap (mdstb, 0, 0, paint); Paint.setxfermode (Smodes[i]); Canvas.drawbitmap (MSRCB, 0, 0, paint); Paint.setxfermode (null); Canvas.restoretocount (SC);
Can see the first drawn DST, then draw the SRC, the final display is srcin that graph: The area shown is the intersection of the two. It shows SRC (the latter). Agree with our previous conclusions.
Effect of 16 kinds, we can freely combine to show different effects.
Well, the principle and the core code are explained. Start writing your own definition view below.
1. Define your own attributes:
<?xml version= "1.0" encoding= "Utf-8"?><resources> <attr name= "Borderradius" format= "Dimension"/ > <attr name= "type" > <enum name= "Circle" value= "0"/> <enum name= "Round" value= "1"/ > </attr> <attr name= "src" format= "reference" ></attr> <declare-styleable Name = "Customimageview" > <attr name= "Borderradius"/> <attr name= "type"/> <attr name= "src "/> </declare-styleable></resources>
2. Get the attributes you define in the construct:
/** * type_circle/type_round */private int type;private static final int type_circle = 0;private static final int Type_r Ound = 1;/** * Picture */private Bitmap msrc;/** * Fillet size */private int mradius;/** * control width */private int mwidth;/** * Control height */p rivate int Mheight;public Customimageview (context context, AttributeSet Attrs) {This (context, attrs, 0);} Public Customimageview (Context context) {This (context, null);} /** * Initialize some of your own defined parameters * * @param context * @param attrs * @param defstyle */public Customimageview (context context, attribut ESet attrs, int defstyle) {Super (context, attrs, Defstyle); TypedArray a = Context.gettheme (). Obtainstyledattributes (Attrs, R.styleable.customimageview, Defstyle, 0); int n = A.getindexcount (); for (int i = 0, i < n; i++) {int attr = A.getindex (i); switch (attr) {case r.styleable.customimageview_s RC:MSRC = Bitmapfactory.decoderesource (Getresources (), A.getresourceid (attr, 0)); break;case R.styleable.customimageview_type:type = A.getint (attr, 0);//Tacit feeling circlebreak;case R.Styleable. Customimageview_borderradius:mradius= a.getdimensionpixelsize (attr, (int) typedvalue.applydimension ( Typedvalue.complex_unit_dip, 10f,getresources (). Getdisplaymetrics ()));//default 10DPbreak;}} A.recycle ();}
3. Get control width height in onmeasure:
/** * Calculate the height and width of the control */@Overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//Super.onmeasure ( Widthmeasurespec, Heightmeasurespec);/** * Set width */int specmode = Measurespec.getmode (widthmeasurespec); int specSize = Measurespec.getsize (WIDTHMEASURESPEC); if (Specmode = = measurespec.exactly)//match_parent, accurate{mwidth = specSize ;} else{//wide int desirebyimg = Getpaddingleft () + getpaddingright () + msrc.getwidth () determined by the picture; if (Specmode = = Measurespec.at_ Most)//Wrap_content{mwidth = Math.min (desirebyimg, specsize);} elsemwidth = Desirebyimg;} /*** * Set Height */specmode = Measurespec.getmode (heightmeasurespec); specsize = Measurespec.getsize (HeightMeasureSpec); if ( Specmode = = measurespec.exactly)//match_parent, accurate{mheight = specsize;} else{int Desire = Getpaddingtop () + GetPad Dingbottom () + msrc.getheight (); if (Specmode = = measurespec.at_most)//Wrap_content{mheight = Math.min (Desire, specSize );} Elsemheight = Desire;} Setmeasureddimension (Mwidth, mheight);}
4. Draw according to type:
/** * * * draw */@Overrideprotected void OnDraw (canvas canvas) {switch (type) {//type_circle draw round case Type_circle:int min = Mat H.min (Mwidth, mheight);/** * length assumptions are inconsistent. Compressed by a small value */msrc = Bitmap.createscaledbitmap (mSrc, Min, Min, false); Canvas.drawbitmap (Createcircleimage (MSRC, Min), 0, 0 , null); Break;case TYPE_ROUND:canvas.drawBitmap (Createroundconerimage (MSRC), 0, 0, NULL); /** * Draw circular picture based on original and variable length * * @param source * @param min * @return */private Bitmap createcircleimage (Bitmap source, int min) {f Inal Paint paint = new paint ();p Aint.setantialias (true); Bitmap target = bitmap.createbitmap (min, Min, config.argb_8888);/** * Produces a canvas of the same size */canvas canvas = new canvas (target);/** * First Draw round */canvas.drawcircle (MIN/2, MIN/2, MIN/2, paint);/** * Use src_in. Refer to the instructions above */paint.setxfermode (new Porterduffxfermode (PorterDuff.Mode.SRC_IN));/** * Draw picture */canvas.drawbitmap (source, 0 , 0, paint); return target;} /** * Add fillet according to original image * * @param source * @return */private Bitmap createroundconerimage (Bitmap source) {Final Paint paint = new paint ();p Aint.setantialias (true); Bitmap target = Bitmap.createbitmap (Mwidth, Mheight, config.argb_8888); Canvas canvas = new canvas (target); RECTF rect = new RECTF (0, 0, source.getwidth (), Source.getheight ()); Canvas.drawroundrect (rect, Mradius, Mradius, paint); Paint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.SRC_IN)); Canvas.drawbitmap (source, 0, 0, paint); return Target;}
OK, I will not parse the code, I define the view this is the fifth article. ,。 Well written, disgusting,,,.
Everybody like one or leave a message. It's kind of a support for me.
source code click to download
========================================= a simple fix, the Headview in the ScrollView and adapterview the abnormal bug============
Post-Repair code download:
source code click to download
Related blog posts, also recommended at the same time:
Android Xfermode Real-round, rounded pictures
Android Bitmapshader Real-round, rounded pictures
Android Perfect for picture fillets and circles (analysis of implementations)