Using Android Bitmapshader to make a rounded head with a border _android

Source: Internet
Author: User
Tags getcolor int size repetition

The effect is as follows:

A brief introduction to Bitmapshader

About Shader What is, what Shader kinds of types and how to use does not belong to the scope of this article, on this aspect is not very understanding of the students, suggested that first to learn Shader the basic use.

BitmapShaderThe main function is through the paint object, the canvas for the specified Bitmap fill, to achieve a series of effects, you can have the following three modes to choose

1. CLAMP -Stretching, here is the last element of the picture, repeated repeatedly, this effect, in the picture is relatively small, and the area to be painted larger time will be more obvious.

2. REPEAT -Repeat, horizontal longitudinal repeated, different from the previous mode, this model in the picture is relatively small can not meet the requirements are, will be in the horizontal portrait of the repeated drawing of graphics.

3. MIRROR -Flip, this pattern REPEAT is similar to the one, except that the repetition here is the flip of repetition, and the effect of origami is almost the same.

And we're going to use the CLAMP pattern, because as long as we control the size of the graphic, we can avoid stretching the image.

Introduction to specific implementation

To customize the image, border width and color, first in the Res/values directory, create a new Attrs.xml file, which will be written below

<?xml version= "1.0" encoding= "Utf-8"?>
<resources>
 <declare-styleable name= "Mycustomview" >
  <attr name= "mborder_color" format= "color" ></attr> <attr name= "mborder_width" format= "
  Dimension "></attr>
  <attr name=" MSRC "format=" reference "></attr>
 </ Declare-styleable>
</resources>

Of course, there are a few other features you can add here. Now that we have defined the attributes we want to use, we need to View parse them and take advantage of them in our customizations, and the parsing process looks like this

 TypedArray type = Context.obtainstyledattributes (Attrs, r.styleable.mycustomview);
 Mbordercolor = Type.getcolor (r.styleable.mycustomview_mborder_color,0);
 mdrawable = type.getdrawable (R.STYLEABLE.MYCUSTOMVIEW_MSRC);

 Convert the obtained drawable into Bitmap
 bitmapdrawable bitmapdrawable = (bitmapdrawable) mdrawable;
 Mbitmap = Bitmapdrawable.getbitmap ();

 Mborderwidth = Type.getdimensionpixelsize (R.styleable.mycustomview_mborder_width, 2);

It is worth noting that the mSrc parsing of attributes, because the acquisition is an Drawable object, we need to convert it to an Bitmap object.

The following is the use of the object we obtained for the Bitmap drawing of the circular head, BitmapShader and Paint the initialization of the following is as follows

  Msrcbitmap = Bitmap.createscaledbitmap (Mbitmap, Mwidth, Mheight, false);
  Mshader = new Bitmapshader (Msrcbitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  Mpaint = new Paint ();
  Mpaint.setshader (Mshader);
  Mradius = (Mwidth-mborderwidth * 2-4)/2;
  Mcirclex = (mwidth)/2;
  Mcircley = (mheight)/2;

Msrcbitmap is the image obtained by the appropriate reduction or amplification to adapt to our graphics requirements, mWidth and here and what is it? mHeight It's actually the values that we're passing in and out of the definition view layout_width layout_height , but I've dealt with them here, which is to select the minimum operation, so that you can avoid the phenomenon that the image fills up with the specified area because it is wide or tall. It is noteworthy that the custom view requires wrap_content special handling, otherwise the system will not display the view of the property. As for how to handle, you can look at this example of the source code, very simple, I believe a lot of people know or say early on the chest.

One more thing to emphasize here is the radius of the mRadius circle that will be drawn, why subtract the width of the border by 2? You know, our circle is drawn according to the width or height specified by the view, and if the circle we are drawing is exactly the incircle of the specified view, where is the border? It's definitely going to be drawn outside the view so that we don't see the full border. So, the point of subtracting is to make room for the border.

After the above, we have already drawn the circle head, the following to draw a border, but it is very simple, I just define an Paint object, and use it to draw a circle, the brush's initialization operation is as follows

  Mborderpaint = new Paint ();
  Mborderpaint.setstyle (Paint.Style.STROKE);
  Mborderpaint.setstrokewidth (mborderwidth);
  Mborderpaint.setcolor (Mbordercolor);
  Mborderpaint.setstrokecap (Paint.Cap.ROUND);

Well, here's what you can onDraw() do in the function, as shown below

 @Override
 protected void OnDraw (Canvas Canvas) {
  super.ondraw (Canvas);
  Canvas.drawcircle (Mcirclex, Mcircley, Mradius, mpaint);
  Canvas.drawcircle (Mcirclex, Mcircley, Mradius, mborderpaint);
 

In this way, the entire effect is completed. Let's take a look at how to use

 <com.example.hwaphon.patheffecttest.myview
   android:layout_width= "wrap_content"
   android:layout_ height= "Wrap_content"
   android:layout_marginbottom= "16DP"
   android:layout_marginright= "8DP"
   app: Mborder_color= "@android: Color/holo_green_light"
   app:mborder_width= "4DP"
   app:msrc= "@drawable/myview_ Test "/>

Note that you must add a phrase to the container

Xmlns:app=http://schemas.android.com/apk/res-auto

The core code of the concrete implementation

Package com.example.hwaphon.patheffecttest;
Import Android.content.Context;
Import Android.content.res.TypedArray;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapShader;
Import Android.graphics.Canvas;
Import Android.graphics.Paint;
Import Android.graphics.Shader;
Import android.graphics.drawable.BitmapDrawable;
Import android.graphics.drawable.Drawable;
Import Android.util.AttributeSet;

Import Android.view.View;
 /** * Created by Hwaphon on 2016/5/12.
 * * public class MyView extends View {private Bitmap mbitmap;
 Private drawable mdrawable;

 Private Bitmap Msrcbitmap;
 Private Bitmapshader Mshader;

 Private Paint Mpaint;

 private int mwidth, mheight;
 private int Mradius;

 private int Mcirclex, Mcircley;
 private int mbordercolor;
 Private Paint Mborderpaint;

 private int mborderwidth;
 Public MyView {This (context, NULL);
  Public MyView (context, AttributeSet attrs) {Super (context, attrs); TypedArray type = Context.obtainstYledattributes (Attrs, R.styleable.mycustomview);
  Mbordercolor = Type.getcolor (r.styleable.mycustomview_mborder_color,0);

  mdrawable = type.getdrawable (R.STYLEABLE.MYCUSTOMVIEW_MSRC);
  Convert the obtained drawable into Bitmap bitmapdrawable bitmapdrawable = (bitmapdrawable) mdrawable;

  Mbitmap = Bitmapdrawable.getbitmap ();
 Mborderwidth = Type.getdimensionpixelsize (R.styleable.mycustomview_mborder_width, 2);  @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (Widthmeasurespec,
  HEIGHTMEASURESPEC);
  Mwidth = Measurewidth (Widthmeasurespec);
  Mheight = Measureheight (Heightmeasurespec); int temp = mwidth > mheight?
  Mheight:mwidth;
  Mwidth = Mheight = temp;
  Initview ();
 Setmeasureddimension (Mwidth, mheight);
  private int measureheight (int heightmeasurespec) {int size = Measurespec.getsize (HEIGHTMEASURESPEC);
  int sizeMode = Measurespec.getmode (Heightmeasurespec);
  int result = 0;
if (SizeMode = = measurespec.exactly) {   result = size;
   else {result = 200;
   if (SizeMode = = measurespec.at_most) {result = Math.min (result, size);
 } return result;
  private int measurewidth (int widthmeasurespec) {int size = Measurespec.getsize (WIDTHMEASURESPEC);
  int sizeMode = Measurespec.getmode (Widthmeasurespec);
  int result = 0;
  if (SizeMode = = measurespec.exactly) {result = size;
   else {result = 200;
   if (SizeMode = = measurespec.at_most) {result = Math.min (result, size);
 } return result;
  } private void Initview () {msrcbitmap = Bitmap.createscaledbitmap (Mbitmap, Mwidth, Mheight, false);
  Mshader = new Bitmapshader (Msrcbitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  Mpaint = new Paint ();
  Mpaint.setshader (Mshader);
  Mradius = (Mwidth-mborderwidth * 2)/2;
  Mcirclex = (mwidth)/2;

  Mcircley = (mheight)/2;
  Mborderpaint = new Paint ();
  Mborderpaint.setstyle (Paint.Style.STROKE);
  Mborderpaint.setstrokewidth (Mborderwidth); MbordeRpaint.setcolor (Mbordercolor);
  Mborderpaint.setstrokejoin (Paint.Join.ROUND);
 Mborderpaint.setstrokecap (Paint.Cap.ROUND);
  } @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
  Canvas.drawcircle (Mcirclex, Mcircley, Mradius, Mpaint);
 Canvas.drawcircle (Mcirclex, Mcircley, Mradius, Mborderpaint); }
}

Summarize

That's what Android uses Bitmapshader to make all the stuff that comes with a rounded head, and hopefully this article will help you when you're developing Android, and if you have questions, you can talk.

Related Article

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.