Android Custom View and properties animation realizes charging progress bar effect _android

Source: Internet
Author: User
Tags border color getcolor set time

Recent projects need to use a similar mobile phone battery charging progress animation effect, before the properties of the animation, is a picture + timer to complete the way, has been learning animation this piece, plus a review of the custom view of the relevant knowledge points, So I'm going to use the attribute animation and custom view to complete this function, and open it up for the people in need to understand the relevant content.

The functionality of this implementation is similar to the following effect:

The next step is to explain how to complete this function, understand the principle, so that you can extrapolate, to achieve other similar animation effects.

Detailed code please see the big screen

Https://github.com/crazyandcoder/ChargeProgress

Graphic parsing

In general, when we customize view, we dissolve the view, break it down into a small part and then draw it together, and follow the same steps for this project. We use Word to simply parse the basic structure of the animation.

For this charging progress view, I've divided it into ABCD four sections, which explain the composition of each section in detail below.

Part A

For a, it is located at the top of the entire view, centered, and is a rounded rectangle.

Part B

For B, it's an important part of the entire view, with C and D two parts, where B's main property is the setting of the background color.

Section C

For C, C is the style of each progress, showing the unfinished progress bar style.

Section D

For D, it's the same as C, but it's a completed progress style, and the difference is that the color is different.

In fact, this progress view graphics structure is still relatively simple, just a few simple rectangles, combined, so for the above analysis, we easily come up with some important attributes.

 <?xml version= "1.0" encoding= "Utf-8"?> <resources> <declare-styleable Name= "Charging_progress" > <!--Item number--> <attr name= "Cgv_item_count" format= "integer"/> <!--boundary width- > <attr name= "cgv_border_width" format= "Dimension"/> <!--border color--> <attr name= "Cgv_border_color" format= "Color"/> <!--fillet radius--> <attr name= "Cgv_border_cornor_radius" format= "Dimension"/> <!-- Charge within each Progress Item module width--> <attr name= "Cgv_item_width" format= "Dimension"/> <!--charging the height of each progress item module--> < attr name= "Cgv_item_height" format= "Dimension"/> <!--charge within each progress item module's foreground color, charging the color--> <attr "Name=" CHARGING_SRC "format=" Color "/> <!--charging the background color of each progress item module, the--> <attr name=" Cgv_item_charging_ Background "format=" Color "/> <!--view background--> <attr name=" cgv_background "format=" Color "/> Declare-styleable> </resources> 

For the above properties, we need to set the custom view in the XML file, and if there is no setting, we will give a default. Then we get these property values in the code.

Border width private float border_width;
Item number private int item_count;
Border width private float item_width;
Border height private float item_height;
View interior Progress foreground view private int item_charging_src;
View inside the progress background color private int item_charging_background;
View background color private int background;
<!--border color--> private int border_color;
Rounded corner radius private float Border_cornor_radius;
Gets the property value set in the XML TypedArray array = mcontext.obtainstyledattributes (Attrs, r.styleable.charging_progress);
Border_width = Array.getdimension (R.styleable.charging_progress_cgv_border_width, dp2px (2));
Item_height = Array.getdimension (R.styleable.charging_progress_cgv_item_height, dp2px (10));
Item_width = Array.getdimension (R.styleable.charging_progress_cgv_item_width, dp2px (20));
ITEM_CHARGING_SRC = Array.getcolor (r.styleable.charging_progress_cgv_item_charging_src, 0xffffea00); Item_charging_background = Array.getcolor (R.styleable.charging_progress_cgv_item_charging_background, 0xff544645)
; Background = Array.getcolor (r.styleable.chargiNg_progress_cgv_background, 0xff463938);
Border_color = Array.getcolor (R.styleable.charging_progress_cgv_border_color, 0xffb49d7c);
Border_cornor_radius = Array.getdimension (R.styleable.charging_progress_cgv_border_cornor_radius, dp2px (2));
Item_count = Array.getint (R.styleable.charging_progress_cgv_item_count, 10); Array.recycle ();

The value of the custom attribute has been obtained, then we will then draw the combined graph specifically.

For a custom view, the first thing to do is to measure the size of the view, and the width and height of view in this project, the width is good calculation, we set the width of the view is equal to ITEM_WIDHT times 2. But for the height, because we set the progress series, that is, the Item_count, also set the height and width of the item, so for the height, we can calculate item_count times item_height, Plus the number of intervals and the top rectangle is the height of the entire view. At the same time, we set the height of the top rectangle equal to Item_height, the width equal to item_widht half, the middle interval equals item_height divided by 2

/**
* Measuring view width and height,
* *
@param widthmeasurespec
* @param heightmeasurespec
* * @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
super.onmeasure (Widthmeasurespec, HEIGHTMEASURESPEC);
Total number of intervals = (item_count+1) multiplied by interval height (equal to half item_height)
//Total =item_count times Item_height + total interval + top one rectangle (height equals item height) Width equals half of the width of item)
mheight = (int) (Item_count * item_height + (Item_count + 1) * ITEM_HEIGHT/2 + item_height);
Mwidth = (int) (2 * item_width);
Setmeasureddimension (Mwidth, mheight);
}

With the above set up, we can follow the step-by-step drawing.

For the coordinate center point is set in the upper-left corner, which is (0,0).

Draw the top of the rectangle

Knowing the origin of the coordinate system, the coordinates of the top rectangle can be computed.

Set the brush first.

Mpaint.setstyle (Paint.Style.STROKE);
Mpaint.setstrokewidth (border_width);
Mpaint.setcolor ((Border_color));

Because the width of the top rectangle equals half of the ITEM_WIDHT, its width equals 1/6 of the width of the entire view,

int left = Mwidth * 3/8;
int top = 0;
int right = 5 * MWIDTH/8;
int bottom = (int) item_height/2;
The top rectangle
RECTF toprect = new RECTF (left, tops, right, bottom);
Canvas.drawroundrect (Toprect, Border_cornor_radius, Border_cornor_radius, Mpaint);

Next, draw the rectangle at the bottom, which is the rectangle that contains the progress item

Total progress background
RECTF border = new RECTF (0, Bottom, mwidth, mheight);
Canvas.drawroundrect (Border, Border_cornor_radius, Border_cornor_radius, Mpaint);

Next, the rectangle for each item is drawn, and the coordinates of each item are in fact regularly traceable.

Draw all progress for
(int i = 1; I <= item_count; i++) {
mpaint.setstyle (Paint.Style.FILL);
Mpaint.setcolor ((Item_charging_background));
RECTF backrect = new RECTF (MWIDTH/4,
(i + 1) * ITEM_HEIGHT/2 + (i-1) * Item_height,
3 * MWIDTH/4,
item _HEIGHT/2 + i * (3 * item_height/2));
Canvas.drawroundrect (Backrect, Border_cornor_radius, Border_cornor_radius, mpaint);

Drawing animations

For the AC animation, the animation is displayed from progress 0 to 100, which is displayed in turn. In fact, it is also for the calculation of coordinates. Then the final feature is the use of animation, we are using attribute animation? Because, the regular animation it does not support Ah, very simple.

For the study of Android properties animation, you can view this article for a little bit more. "Android Animation Understanding"

1. Interactive animation

/**
* Draw ac Animation
*
* @param canvas * *
private void Drawacanimaiton (canvas canvas) {
Int j = Getprogress ()/item_count;
The progress has been charged for
(int i = Item_count i >= (item_count-j); i--) {
RECTF backrect = new RECTF (MWIDTH/4,
(i + 1) * ITEM_HEIGHT/2 + (i-1) * Item_height,
3 * MWIDTH/4,
ITEM_HEIGHT/2 + i * (3 * item_height/2)); 
   canvas.drawroundrect (Backrect, Border_cornor_radius, Border_cornor_radius, mpaint);
Mpaint.setstyle (Paint.Style.FILL);
Mpaint.setcolor (ITEM_CHARGING_SRC);
Canvas.drawroundrect (Backrect, Border_cornor_radius, Border_cornor_radius, mpaint);
}

We first get the current progress and then populate it with the background, which is the completed progress representation.

Then use the animation, we set the progress of 100, that is, full, and then set the animation time is 10 seconds, for the following animation implementation principle? Actually very simple, get the current progress, and then start from 0, and then draw the progress, know that the drawing of the progress of 100 is the overall progress, and finally loop to execute the animation.

/**
* Set AC animation
/public void Setacanimation () {
chargetype = AC;
Animac = Objectanimator.ofint (This, "progress");
Animac.setduration (1000);
Animac.setinterpolator (New Linearinterpolator ());
Animac.setrepeatcount (valueanimator.infinite);
Animac.addupdatelistener (New Valueanimator.animatorupdatelistener () {
@Override public
Void Onanimationupdate (Valueanimator animation) {
invalidate ();
}
});
Animac.start ();
}

2, DC animation

For DC animation is a little more complicated. When we set the schedule, we need to draw the completed progress in advance, and then flash the animation at the next progress, so how do we do it?

First look at the drawing code:

/** * DC Animation * * @param canvas */private void drawdcaniamtion (canvas canvas) {Int j = getprogress ()/item_count;  Progress for (int i = Item_count i > (item_count-j); i--) {RECTF backrect = new RECTF (MWIDTH/4, (i + 1) * Item_height/
2 + (i-1) * item_height, 3 * MWIDTH/4, ITEM_HEIGHT/2 + i * (3 * item_height/2));
Canvas.drawroundrect (Backrect, Border_cornor_radius, Border_cornor_radius, Mpaint);
Mpaint.setstyle (Paint.Style.FILL);
Mpaint.setcolor (ITEM_CHARGING_SRC);
Canvas.drawroundrect (Backrect, Border_cornor_radius, Border_cornor_radius, Mpaint);
//Next progress, hide and show alternating animation int i = Item_count-j;
if (i > 0) {RECTF backrect = new RECTF (MWIDTH/4, (i + 1) * ITEM_HEIGHT/2 + (i-1) * item_height, 3 * MWIDTH/4,
ITEM_HEIGHT/2 + i * (3 * item_height/2));
Mpaint.setstyle (Paint.Style.FILL);
if (show) {Mpaint.setcolor ((ITEM_CHARGING_SRC));} else {Mpaint.setcolor ((item_charging_background));} Canvas.drawroundrect (Backrect, Border_cornor_radius, Border_cornor_radius, Mpaint); }
}

First draw the completed progress, and then draw the blinking part.

/**
* DC Animation
*
* @param progress
*
/public void setdcanimation (final int progress) {
Chargetype = DC;
ANIMATORDC = valueanimator.offloat (0, 1);
Animatordc.setinterpolator (New Linearinterpolator ());
Animatordc.setduration (1000);
Animatordc.setrepeatcount ( -1);
Animatordc.setrepeatmode (Valueanimator.restart);
Animatordc.addupdatelistener (New Valueanimator.animatorupdatelistener () {
@Override public
Void Onanimationupdate (Valueanimator animation) {
float value = (float) animation.getanimatedvalue ();
if (value > 0.5) {show
= true;
} else {show
= false;
} Setprogress (progress);
}
);
Animatordc.start ();
}

Come here, it is very clear. For DC animations, we use the attribute animation in this valueanimator class, which means a smooth transition from 0 to 1, within the set time. Our principle is that when more than 0.5 to set the gray progress, when less than 0.5 of the set of bright light progress, and then refresh the view can.

The above is a small set to introduce the Android custom view and property animation to achieve charging progress bar effect, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

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.