Android implements custom round, fillet, and Ellipse imageview (using Xfermode Graphics Rendering method)

Source: Internet
Author: User
Tags transparent color

A: Introduction:

In the previous article, "Android realizes round, fillet and ellipse custom picture view (using Bitmapshader Graphics Rendering method)" , the Bitmapshader method is used to implement custom imageview such as round and rounded corners, In this article, we will use the more common Xfermode rendering mode scheme to realize the imageview of circular, rounded and elliptical styles, and this example is also directly inheriting ImageView,

This can save a lot of things, such as measuring steps, and do not need to write the method of setting the picture, this article uses the dst_in mode in the Xfermode mode to achieve the effect, of course, you can also use other modes, such as src_in can achieve this effect.

(as usual the full source code at the end of the article given ha)

Two::

Three, Xfermode rendering mode introduction:

Xfermode affects how new colors are drawn on canvas-already-existing images
* Under normal circumstances, draw a new shape on the image, and if the new paint is not transparent, it will obscure the color below.
* If the new paint is transparent, it will be dyed to the following color

The following subclass of Xfermode can change this behavior:

AVOIDXFERMODE specifies a color and tolerance, forcing paint to avoid drawing on it (or just drawing on it).

Pixelxorxfermode a simple pixel XOR operation is applied when the existing color is overwritten.

Porterduffxfermode This is a very powerful conversion mode, using it, you can use any of the 16 porter-duff rules of the image composition to control how paint interacts with existing canvas images.

I have to mention the classic picture here:

The above 16 modes are described below:

From the above we can see that Porterduff.mode is an enumeration class with a total of 16 enumeration values:

1.porterduff.mode.clear

The drawing is not submitted to the canvas.
2.porterduff.mode.src

Show Top Draw picture
3.porterduff.mode.dst

Show Lower drawing pictures
4.porterduff.mode.src_over

Normal drawing shows that the upper and lower layers are drawn with overlapping covers.
5.porterduff.mode.dst_over

The upper and lower layers are displayed. The lower level is shown on the home.
6.porterduff.mode.src_in

Draw the intersection of two layers. Displays the upper layer.
7.porterduff.mode.dst_in

Draw the intersection of two layers. Displays the lower layer.
8.porterduff.mode.src_out

Draw the non-intersecting portion of the upper layer.
9.porterduff.mode.dst_out

Remove the layer to draw the non-intersecting part.
10.porterduff.mode.src_atop

Remove the non-intersecting part of the layer from the upper intersection section
11.porterduff.mode.dst_atop

Take the upper non-intersecting part and the lower part of the intersection
12.porterduff.mode.xor

XOR: Remove the two Layer intersection section
13.porterduff.mode.darken

Take two layers of all areas, the intersection part of the color deepened
14.porterduff.mode.lighten

Take two layers all, light the intersection part color
15.porterduff.mode.multiply

Take two layer intersection part overlay color
16.porterduff.mode.screen

Take two layers of all areas, the intersection part becomes transparent color

Iv. implementation of custom ImageView for circular, rounded corners and ellipses

1, measuring the size of the view, the circle for special treatment

/*** Measure the size of the view*/@Overrideprotected voidOnmeasure (intWidthmeasurespec,intHeightmeasurespec) {        //TODO auto-generated Method Stub        Super. Onmeasure (Widthmeasurespec, Heightmeasurespec); //if the type is circular, force the width and height of the view to be consistent and take a smaller value with a wide height        if(Mtype = =type_circle) {            intwidth =math.min (Getmeasuredwidth (), Getmeasuredheight ());        Setmeasureddimension (width, width); }    }

2, Draw different graphics bitmap, for OnDraw () to draw the time with

/*** Draw different graphics bitmap*/    PrivateBitmap Getdrawbitmap () {Bitmap Bitmap=Bitmap.createbitmap (GetWidth (), GetHeight (), Bitmap.Config.ARGB_8888); Canvas Canvas=NewCanvas (bitmap); Paint Paint=NewPaint (Paint.anti_alias_flag);            Paint.setcolor (Color.Black); if(Mtype = =type_circle) {//Draw a circleCanvas.drawcircle (GetWidth ()/2, getwidth ()/2, getwidth ()/2, paint); }Else if(Mtype = =type_round) {//Draw rounded rectanglesCanvas.drawroundrect (NewRECTF (0, 0, GetWidth (), GetHeight ()), Mroundborderradius, Mroundborderradius, paint); }Else if(Mtype = =type_oval) {         //Draw EllipseCanvas.drawoval (NewRECTF (0, 0, GetWidth (), GetHeight ()), mpaint); }          returnbitmap; }

3. Draw in OnDraw ()

/*** Draw the contents of the View*/@Overrideprotected voidOnDraw (canvas canvas) {//TODO auto-generated Method Stub//Remove the bitmap from the cacheBitmap bmp = (Mbufferbitmap = =NULL?NULL: Mbufferbitmap.get ()); if(BMP = =NULL||bmp.isrecycled ()) {            //If there are no cache conditions//Get drawableDrawable drawable =getdrawable (); //get drawable's wide height            intDwidth =drawable.getintrinsicwidth (); intDheight =drawable.getintrinsicheight (); LOG.V ("Czm", "dwidth=" +dwidth+ ", width=" +getwidth ()); if(NULL!=drawable) {BMP=Bitmap.createbitmap (GetWidth (), GetHeight (), config.argb_8888); floatScale = 1.0f; //Create a canvasCanvas Drawcanvas =NewCanvas (BMP); //Calculates the zoom ratio according to the width of the bitmap and the width of the view, because the src width is set to a high//The ratio may be different from the imageview ratio, where we do not want the picture to be distorted;                                if(Mtype = =type_circle) {//if it's a circleScale = GetWidth () * 1.0F/math.min (Dwidth, dheight); }Else if(mtype = = Type_round | | mtype = =type_oval) {//If it is a rounded rectangle or ellipse//if the width or height of the picture does not match the width and height of the view, the scale that needs to be scaled is calculated;//The width of the scaled image must be greater than the width of our view, so we take a large value here;Scale = Math.max (getwidth () * 1.0f/Dwidth, getheight ()* 1.0f/dheight); } log.v ("Czm", "scale=" +Scale ); //set bounds based on scale, which is equivalent to zooming the pictureDrawable.setbounds (0, 0, (int) (Scale * dwidth), (int) (Scale *dheight));                Drawable.draw (Drawcanvas); //gets the bitmap, which is the bitmap of a circle, fillet, or ellipse                if(Mmaskbitmap = =NULL||mmaskbitmap.isrecycled ()) {Mmaskbitmap=Getdrawbitmap (); }                //set Xfermode rendering mode for paintMpaint.reset (); Mpaint.setfilterbitmap (false);                Mpaint.setxfermode (Mxfermode); //Draw different ShapesDrawcanvas.drawbitmap (mmaskbitmap, 0, 0, Mpaint); Mpaint.setxfermode (NULL); //draw the prepared bitmap .Canvas.drawbitmap (BMP, 0, 0,NULL); //bitmap cache, avoid each call to OnDraw, allocate memoryMbufferbitmap =NewWeakreference<bitmap>(BMP); }                    }Else{            //if the cache still existsMpaint.setxfermode (NULL); Canvas.drawbitmap (BMP,0.0f, 0.0f, Mpaint); return; }    }

4, because of the use of weak reference caching technology, so you need to rewrite the invalidate () method to do some release of recycling resources, such as processing:

 /**   * because caching technology is used, So we need to do some recycling in invalidate.  */  public  void   invalidate () { //  TODO auto-generated m        Ethod stub  mbufferbitmap = null   if  (mmaskbitmap! = null  ) {mmaskbitmap.recycle ();        Mmaskbitmap  = null  ;     super  .invalidate (); }

V. Implementation of the View layout:

<scrollview xmlns:android= "Http://schemas.android.com/apk/res/android"Xmlns:tools= "Http://schemas.android.com/tools"Android:layout_width= "Match_parent"Android:layout_height= "Match_parent" > <LinearLayout android:layout_width= "Match_parent"Android:layout_height= "Wrap_content"android:gravity= "Center_horizontal"Android:layout_margintop= "10DP"Android:layout_marginbottom= "55DP"android:orientation= "Vertical" > <Com.czm.myroundimageview.XCRoundImageViewByXfermode Android:id= "@+id/cicleimageview"Android:layout_width= "150DP"Android:layout_height= "150DP"android:src= "@drawable/img1"/> <Com.czm.myroundimageview.XCRoundImageViewByXfermode Android:id= "@+id/roundrectimageview"Android:layout_width= "125DP"Android:layout_height= "145DP"Android:layout_margintop= "15DP"android:src= "@drawable/img2"/> <Com.czm.myroundimageview.XCRoundImageViewByXfermode Android:id= "@+id/ovalimageview"Android:layout_width= "140DP"Android:layout_height= "184DP"Android:layout_margintop= "15DP"android:src= "@drawable/img3"/> </LinearLayout></ScrollView>

Vi. use and testing of custom ImageView

The custom imageview that are drawn directly above is written, and the following is the custom ImageView, using the same method as normal ImageView, as normal controls.

 PackageCom.czm.myroundimageview;Importandroid.app.Activity;ImportAndroid.os.Bundle; Public classMainactivityextendsActivity {PrivateXcroundimageviewbyxfermode Circleimageview;//Circular Picture    PrivateXcroundimageviewbyxfermode Roundrectimageview;//Rounded Rectangle Picture    PrivateXcroundimageviewbyxfermode Ovalimageview;//Oval Image@Overrideprotected voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate);        Setcontentview (R.layout.activity_main);    Initviews (); }    /*** Initialize views*/    Private voidinitviews () {Circleimageview=(Xcroundimageviewbyxfermode) Findviewbyid (R.id.cicleimageview); Roundrectimageview=(Xcroundimageviewbyxfermode) Findviewbyid (R.id.roundrectimageview); Ovalimageview=(Xcroundimageviewbyxfermode) Findviewbyid (R.id.ovalimageview);        Roundrectimageview.settype (Xcroundimageviewbyxfermode.type_round); Roundrectimageview.setroundborderradius (100);        Ovalimageview.settype (Xcroundimageviewbyxfermode.type_oval); Ovalimageview.setroundborderradius (50); }   }

Seven, as usual, finally provide full source download

Real Theme Park net :http://www.zhentiyuan.com

Download Now:http://download.csdn.net/detail/jczmdeveloper/8311659

Android implements custom round, fillet, and Ellipse imageview (using Xfermode Graphics Rendering method)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.