Android Custom View Imitation Micro Bo motion integral animation effect _android

Source: Internet
Author: User
Tags drawtext getcolor

Custom view has always been its own short board, taking advantage of the company's project when not nervous, more to strengthen this practice. This series of articles mainly records their experience in the learning process of customizing view.

When you brush Weibo, you find that the Micro-blog movement interface, the display of the motion integral has a very good-looking animation effect. OK, just start with my custom view path!

Take a look at the final effect:

Fractional color, fractional size, the color of the outer circle, the color of the arc to support their own settings, the overall or micro-bo that very similar. Let's take a look at how custom view is implemented Step-by-step:

1. Customize View Properties:
Create a attrs.xml under res/values/, define our attributes inside, and declare our entire style.

<?xml version= "1.0" encoding= "Utf-8"?>
<resources>
 //custom property name, defining public properties
 <attr name= " Titlesize "format=" Dimension "></attr>
 <attr name=" titlecolor "format=" Color "></attr>
 <attr name= "outcirclecolor" format= "color" ></attr>
 <attr name= "Incirclecolor" Color "></attr>
 <attr name=" LineColor "format=" color "></attr>

 //Custom control theme Styles
 < Declare-styleable name= "Mysportview" >
  <attr name= "titlesize" ></attr>
  <attr name= " Titlecolor "></attr>
  <attr name=" Outcirclecolor "></attr>
  <attr name=" Incirclecolor "></attr>
 </declare-styleable>
</resources>

The font size, font color, outer circle color, Arc color 4 properties, format is the value type of the property.
Then we'll declare our custom view in the layout file:

    <com.example.tangyangkai.myview.mysportview
    android:id= "@+id/sport_view"
    android:layout_width= " 200DP "
    android:layout_height=" 200DP "
    android:layout_margin=" 20DP "
    app:incirclecolor=" @color/strong "
    app:outcirclecolor=" @color/coloraccent "
    app:titlecolor=" @color/colorprimary "
    app:titlesize=" 50DP "/>

Custom View Properties We can set it ourselves, remember to finally introduce our namespaces,
xmlns:app= "Http://schemas.Android.com/apk/res-auto"

2. Get the properties of the custom view:

/** * Created by Tangyangkai on 16/5/23.
 */public class Mysportview extends View {private String text;
 private int textcolor;
 private int textsize;
 private int outcirclecolor;
 private int incirclecolor;
 Private Paint mpaint, Circlepaint;
 Draw the range of text private Rect mbound;
 Private RECTF Circlerect;
 private float Mcurrentangle;
 private float Mstartsweepvalue;

 private int mcurrentpercent, mtargetpercent;
 Public Mysportview {This (context, NULL);
 Public Mysportview (context, AttributeSet attrs) {This (context, attrs, 0);


  Public Mysportview (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr); Get our Custom style properties TypedArray array = Context.gettheme (). Obtainstyledattributes (Attrs, R.styleable.mysportview,
  defstyleattr, 0);
  int n = array.getindexcount ();
   for (int i = 0; i < n; i++) {int attr = Array.getindex (i); Switch (attr) {case R.styleable.mysportview_titlecolor://defaultThe color is set to black TextColor = Array.getcolor (attr, Color.Black);
    Break Case R.styleable.mysportview_titlesize://The default setting is 16sp,typevalue can also convert sp to px textsize = array.getdimensionpixelsize
     (attr, (int) typedvalue.applydimension (typedvalue.complex_unit_sp, Getresources (). Getdisplaymetrics ());
    Break
     Case R.styleable.mysportview_outcirclecolor://Default color set to Black Outcirclecolor = Array.getcolor (attr, Color.Black);
    Break
     Case R.styleable.mysportview_incirclecolor://Default color set to Black Incirclecolor = Array.getcolor (attr, Color.Black);

   Break
  } array.recycle ();

 Init ();
  }//Initialize private void init () {//create brush mpaint = new Paint ();
  Circlepaint = new Paint ();
  Sets whether Anti-aliasing Mpaint.setantialias (true);
  Ring Starting angle ( -90° for 12 o'clock direction) Mstartsweepvalue =-90;
  Current angle Mcurrentangle = 0;
  Current percent mcurrentpercent = 0;
 Draw the range of text Mbound = new Rect ();

 }

Custom view generally requires the implementation of three construction methods, the three constructs are one layer of the call layer, is a progressive relationship. So, we just need to get the view property in the last constructor.

Step One: get the theme style array of the custom control through the Theme.obtainstyledattributes () method;

Step two : Iterate through each property to get the value of the corresponding property, which is the attribute value we write in the XML layout file;

Step three : Remember to call Array.recycle () to reclaim resources after the end of the loop; The fourth step is to do the necessary initialization and not recommend instantiating the object in the OnDraw process, because it is a process that repeats frequently, New is the need to allocate memory space, if in a frequent repetition of the process of a large number of new objects will cause memory waste.

3. Rewrite the Onmesure method to determine the view size:
when you do not rewrite the Onmeasure method, the system calls the default Onmeasure method:

 @Override
 protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
  super.onmeasure ( Widthmeasurespec, Heightmeasurespec);
 

The purpose of this method is to measure the size of the control. In fact, the Android system in the load layout is the system to measure the size of each child view to tell the parent view I need to occupy a lot of space, and then the parent view will be based on their size to decide how much space allocated to the child view. There are three kinds of specmode models in Measurespec:

measurespec.exactly: The parent view expects the size of the child view to be the size specified in the specsize, usually by setting a definite value or match_parent
measurespec.at_most: The size of the child view is the maximum size in the specsize, which means that the child layout is restricted to a maximum value, typically warp_content
measurespec.unspecified: The parent view does not impose any restrictions on the child view, it can get any size it wants, and it shows how big the child layout wants, and rarely uses it.

What about the effect of "wrap_content"? No hurry, only rewrite the Onmeasure method:

 @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//If a fixed value is set inside the layout, take the fixed value in the layout and the values in the parent layout size.
  The minimum value, or the size int widthmode = Measurespec.getmode (Widthmeasurespec) of the parent layout if the match_parent is set;
  int widthsize = measurespec.getsize (Widthmeasurespec);
  int heightmode = Measurespec.getmode (Heightmeasurespec);
  int heightsize = measurespec.getsize (Heightmeasurespec);
  int width;
  int height;
  if (Widthmode = = measurespec.exactly) {width = widthsize;
   else {mpaint.settextsize (TEXTSIZE);
   Mpaint.gettextbounds (text, 0, Text.length (), mbound);
   float textWidth = Mbound.width ();
   int desired = (int) (Getpaddingleft () + TextWidth + getpaddingright ());
  width = desired;
  } if (Heightmode = = measurespec.exactly) {height = heightsize;
   else {mpaint.settextsize (TEXTSIZE);
   Mpaint.gettextbounds (text, 0, Text.length (), mbound);
   float textHeight = Mbound.height ();
   int desired = (int) (Getpaddingtop () + TextHeight + getpaddingbottom ());height = desired;
  //Call the parent class method and tell the parent layout the size of the view.
 Setmeasureddimension (width, height);

 }

4. Overriding the OnDraw method for painting:

 @Override protected void OnDraw (Canvas Canvas) {//Set outer circle color Mpaint.setcolor (outcirclecolor);
  Set Outer circle as Hollow Mpaint.setstyle (Paint.Style.STROKE);
  Draw Outer Circle Canvas.drawcircle (GetWidth ()/2, getwidth ()/2, getwidth ()/2, mpaint);
  Sets the font color Mpaint.setcolor (textcolor);
  Sets the font size mpaint.settextsize (TEXTSIZE);
  Gets the width and height range of the font text = string.valueof (mcurrentpercent);
  Mpaint.gettextbounds (text, 0, Text.length (), mbound);

  Draw Font Canvas.drawtext (text, getwidth ()/2-mbound.width ()/2, getwidth ()/2 + mbound.height ()/2, mpaint);
  Sets the font size mpaint.settextsize (TEXTSIZE/3);

  Draw Font Canvas.drawtext ("Min", getwidth () * 3/4, GetWidth ()/3, mpaint);
  Circlepaint.setantialias (TRUE);
  Circlepaint.setstyle (Paint.Style.STROKE);
  Set the width of the arc circlepaint.setstrokewidth (10);
  Set the color of the arc circlepaint.setcolor (Incirclecolor);
  Arc Range circlerect = new RECTF (a), getwidth ()-getwidth ()-20); Draw Arc Canvas.drawarc (Circlerect, Mstartsweepvalue, Mcurrentangle, FALSE, circlepaint);
   Determine if the current percentage is less than the percentage of the set target if (Mcurrentpercent < mtargetpercent) {//Current percent +1 mcurrentpercent = 1;
   Current angle +360 mcurrentangle = 3.6;
  Every 100ms redraw postinvalidatedelayed (100);

 }
 }

Code comments written in the gray often detailed, here and you share a small skill, is in rewriting the OnDraw method before, oneself in the book to draw again, coordinates, position and so on a simple callout. It's really practical!!!.

(1) When the text is drawn, the second argument passed in and the third parameter is the position of point A in the diagram

Copy Code code as follows:
Canvas.drawtext (text, getwidth ()/2-mbound.width ()/2, getwidth ()/2 + mbound.height ()/2, mpaint);

(2) Draw the arc first to determine the range of arcs, the incoming four parameters are the internal circle in the figure of the external square coordinates
Copy Code code as follows:
Circlerect = new RECTF (a), getwidth ()-getwidth ()-20);

(3) Draw the arc, the parameters are arc range, the starting angle; the angle of the arc; the fourth is true, the center of the circle is included when the arc is drawn, which is usually used to draw a pie, we choose false; Arc brush
Copy Code code as follows:
Canvas.drawarc (Circlerect, Mstartsweepvalue, Mcurrentangle, False, Circlepaint);

Finally, the score increase and ARC animation implementation, then need to call postinvalidatedelayed This method, this method will call the view of the invalidate () method at a specified time, and eventually will call the OnDraw method, complete a cycle. So if you want to control animation, we can define a global mcurrentpercent and Mcurrentangle variable, in the OnDraw method of continuous increment, to achieve the effect of animation.

OK, here is the realization of the custom view is all over, in fact, comb it again, not so scary.

The next custom view, see not scattered!

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.