Android Custom View implementation damping effect of loading animation _android

Source: Internet
Author: User
Tags drawtext

Effect:

Need knowledge:

1. two times Bezier curve

2. Animation knowledge

3. Basic Custom View Knowledge

Let's explain what the damping motion is.

Damping is the vibration of vibration system, which is caused by friction and medium resistance or other energy consumption, and the amplitude decreases with time, also known as reduction vibration and attenuation vibration. [1] Whether it is a spring vibrator or a pendulum because the external friction and medium resistance is always there, in the vibration process to constantly overcome the external resistance work, energy consumption, the amplitude will gradually reduce, after a period of time, the vibration will completely stop. The vibration that the amplitude decreases with time is called damped oscillation. Because the amplitude is related to the energy of the vibration, damping is the vibration that decreases the energy. damped vibration is harmonic. Damped damping system belongs to dissipation system. Damping here refers to the characteristic of the vibration amplitude decreasing gradually due to the external action or the inherent reason of the system itself, and the quantitative representation of the characteristic of any vibrating system in vibration.

In this case the text part of the sunken is this effect, of course, this article knowledge with you simple use.

The effect of beating fruit is realized

Anatomy: From the above effect picture is very good from the top down and then the upward rotation can be.

So let's start by customizing a view inheritance Framelayout

public Class I extends Framelayout {public I
(context) {
super (context);
}
Public I (context, AttributeSet attrs) {
Super (context, attrs);
}
}

Need material as follows three picture:



Maybe someone will ask me to see you. The effect map becomes up or down at the top or bottom. Do you have three sheets?

A: Rotate 180 degrees to the top or bottom

We now define several variables in the customization

Used to record the current picture using which
int indeximgflag = 0 in the array;
Sinking picture the ID
int Allimgdown [] = {R.MIPMAP.P2,R.MIPMAP.P4,R.MIPMAP.P6,R.MIPMAP.P8} in front of three pictures;
Animation effects a sinking or bouncing time animationduration*2= a full animation time
int animationduration = 1000;
Bouncing pictures of
ImageView IV;
Picture sinking height (i.e. distance from highest to lowest point)
int downheight = 2;
Falling animation
private Animation Translatedown;
Play animation
private Animation translateup;
Rotating animation
private objectanimator rotation;

Let's take a look at the method of initializing the animation (this method uses recursive thinking to achieve an infinite play animation, you can see where not to understand)

Initialize bounce animation public void Myanmation () {//sinking effect Animation Translatedown = new Translateanimation (animation.relative_to_self,0,
animation.relative_to_self,0, Animation.relative_to_self,0,animation.relative_to_self,downheight);
Translatedown.setduration (animationduration);
Setting an interpolation animation will play more and more quickly to simulate gravity translatedown.setinterpolator (new Accelerateinterpolator ());
Up animation translateup = new Translateanimation (animation.relative_to_self,0,animation.relative_to_self,0,
animation.relative_to_self,downheight,animation.relative_to_self,0);
Translateup.setduration (animationduration);
Setting an interpolation animation will play more and more slowly to simulate the inverse gravity translateup.setinterpolator (new Decelerateinterpolator ()); Play Boot Translatedown.setanimationlistener (new Animation.animationlistener () {@Override public void when the sinking animation completes Onanimationstart (Animation Animation) {Iv.setimageresource (Allimgdown[indeximgflag]); rotation =
Objectanimator.offloat (iv, "rotation", 180f, 360f);
Rotation.setduration (1000);
Rotation.start (); @Override public void OnanimationendImation animation) {iv.startanimation (translateup);} @Override public void Onanimationrepeat (animation animation) {}})
; Plays the move down animation Translateup.setanimationlistener when the move animation completes (new Animation.animationlistener () {@Override public void
Onanimationstart (Animation Animation) {Indeximgflag = 1+indeximgflag>=allimgdown.length?0:1+indeximgflag;
Iv.setimageresource (Allimgdown[indeximgflag]);
rotation = Objectanimator.offloat (iv, "rotation", 0.0f, 180f);
Rotation.setduration (1000);
Rotation.start (); @Override public void Onanimationend (Animation Animation) {//recursive iv.startanimation (Translatedown);} @Override public Vo
ID onanimationrepeat (Animation Animation) {}}); }

Above code knowledge:

Interpolation: Allows an animation to speed up animation or slow down at a certain time during playback

Set an interpolation animation will play more and more quickly simulate gravity

1.translatedown.setinterpolator (New Accelerateinterpolator ());

This interpolation rate represents the graph:

You can see from the slope that using this interpolation animation will be quicker and faster. Meaning is the effect of gravity when imitating falling

Set an interpolation animation will play more slowly simulate anti-gravity

2. Translateup.setinterpolator (New Decelerateinterpolator ());

Rate Chart:

Finally we initialize the picture control to our custom view

private void Init () {
//Initialize bounce picture control
IV = new ImageView (GetContext ());
Viewgroup.layoutparams params = new Viewgroup.layoutparams (
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Iv.setlayoutparams (params);
Iv.setimageresource (Allimgdown[0]);
This.addview (iv);
Iv.measure (0,0);
Iv.getviewtreeobserver (). Addongloballayoutlistener (New Viewtreeobserver.ongloballayoutlistener () {
@ Override public
void Ongloballayout () {
if (!flagmeure)
{
flagmeure =true;
Since the drawing text is started by the baseline
Path.moveto (Iv.getx ()-textwidth/2+iv.getwidth ()/2, textheight+iv.getheight () +downheight* Iv.getheight ());
Calculate maximum elastic
maxelasticfactor = (float) (textheight/elastic);
Initialize Bezier curves
path.rquadto (TEXTWIDTH/2, 0, textWidth, 0);
Initialize the up and down animation
myanmation ();
Iv.startanimation (Translatedown);}}
);

The above knowledge:

1. Iv.measure (0,0); proactively notify the system to measure this control or iv.getwidth = 0;
The following is the same as the same IV measurement when the callback is not iv.getwidth = 0;
2. Iv.getviewtreeobserver (). Addongloballayoutlistener (New Viewtreeobserver.ongloballayoutlistener () { 
... 
}

Reason: TextView TV = new TextView () or Layoutinflat fill layout are

Asynchronous so you get the natural return 0 when new comes out or fills

So far you only need to call Init () in the onsizechanged callback method of the custom view to see the animated motion of the animation

@Override
protected void onsizechanged (int w, int h, int oldw, int oldh) {
super.onsizechanged (W, H, OLDW, OLDH); C8/>init ();
}

This method is invoked after the Onmesure method completes, so you can get a custom view's width in this way.

Effect Chart:

Draw text into U-shaped

First you need to know the following knowledge

Bezier Curves: Specific Learning

Here we use 2 of this Bezier curve

Let's see what's probably called the 2-time Bezier curve.

Let's take a look at the three dots p0 p1 P2 We call P0 the start point P1 as the control point P2 end point, you can use the Bezier formula to draw the graph curve

There is no need for us to delve into how to draw it. And I don't need you to understand the basics of math.

So how do we draw in Andong?

Path PATH = new Path ();
P0 x Y coordinate
path.moveto (p0.x,y);
Path.rquadto (P1.X,P1.Y,P2.X,P2.Y);

This is the API call method is not very simple? Then you ask, so how do you draw it?
It's very simple to call in the Dispatchdraw method or OnDraw

@Override
protected void Dispatchdraw (Canvas Canvas) {
super.dispatchdraw (Canvas);
Canvas.drawpath (Path,paint);
}

So the effect you draw should be the same as the one in PS with a pen. The pen tool is a two-time Bezier curve.


(Borrow the picture)

If your three point position is the same as the newly opened picture p0 P1 P2 (P1 at P0 upper right and P1 on the upper left), the display on the screen is as follows

Here, with the expansion, the difference between Dispatchdraw and OnDraw

If your custom view is inherited view then call Ondraw->>dispatchdraw first

If your custom view is inherited ViewGroup then skip the OnDraw method directly call Dispathchdraw here Special attention!! We inherit framelayout in this case, and Framelayout is inherited from ViewGroup so ....

So how do we go back to the theme of how to draw a U-shaped text? Simple means to write as we draw the curve on the above: the text is "CSDN Open source China" how to let these words on our curve written out?

Here is a description of an API

Canvas.drawtextonpath ()

First argument: literal type is a string

The second argument: The path is the two Bezier curve in front of us

Third parameter: Position along the path text white offset

Fourth parameter: The offset of the height of the path

Hoffset:

The distance along the path to add to the text ' s starting position

Voffset:

The distance above (-) or below (+) the path to position the text
OK, let's see what he can draw.

The more you understand the Bezier curve, the more images you can draw, and of course you don't have to use Bezier curves.

To determine the starting point of a Bezier curve

We're looking back at our effect chart.

We can see that the text should be in the position of IV (the center of the bounce picture and right at the end of the IV projectile)

Here we first add the knowledge in consideration of the calculation

Let's take a look at the text measurement.

When we call the API for drawing text

Canvas.drawtextonpath or Canvas.drawtext are drawn from the baseline, which means that the baseline on the way begins to draw.

Such as:

Canvas.drawtext ("Fmy", 0,0,paint);

Then you will not see text that can only be seen on the screen below the bottom of the text:

Another empathy API Drawtextonpath is also

Take a look at a few simple APIs

1. Paint.measuretext ("fmy"); Returns the width of the write fmy text under this brush paint

The following API writes the text to this rectangle by the value of the bottom at the bottom right of the left top

rect.right-rect.left= Text width 
rect.bottom-rect.top= text height
//Rectangle
Rect rect = new rect ();
The purpose of drawing text into the rectangle is to measure height
paint.gettextbounds (printtext, 0, Printtext.length (), rect);

So, look at this:

private void Init () {//Initialize bounce Picture Control IV = New ImageView (GetContext ());
Viewgroup.layoutparams params = new Viewgroup.layoutparams (ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Iv.setlayoutparams (params);
Iv.setimageresource (Allimgdown[0]);
This.addview (iv);
The initialization of the brush paint = new paint ();
Paint.setstrokewidth (1);
Paint.setcolor (Color.cyan);
Paint.setstyle (Paint.Style.FILL);
Paint.settextsize (50);
Paint.setantialias (TRUE);
Rectangular Rect Rect = new Rect ();
The purpose of drawing text into the rectangle is to measure height paint.gettextbounds (printtext, 0, Printtext.length (), rect);
Text width textWidth = paint.measuretext (Printtext);
Get text Height textHeight = rect.bottom-rect.top;
Initializes path PATH = new Path ();
Iv.setx (GetWidth ()/2);
Iv.measure (0,0);
Iv.getviewtreeobserver (). Addongloballayoutlistener (New Viewtreeobserver.ongloballayoutlistener () {@Override public void Ongloballayout () {if (!flagmeure) {flagmeure =true;//Because the drawing text is started by the baseline Path.moveto (Iv.getx ()-textwidth/2+ Iv.getwidth ()/2, textheight+iv.getheight () +downheighT*iv.getheight ());
Calculate Maximum Elastic Maxelasticfactor = (float) (textheight/elastic);
Initialize Bezier curves path.rquadto (TEXTWIDTH/2, 0, textWidth, 0);
Initialize the up and down animation myanmation ();
Iv.startanimation (Translatedown);
}
}
}); }

We are now writing a class when the IV picture (bounce) hits the top of the text, setting a listener time is just the time to make the text sag in the back to normal during the period up to the top

Used to play text sinking and floating animation incoming values must be the picture sinks and rises once a time public
void initanimation (int duration) {
//here why MAXELASTICFACTOR/4 good-looking ... Another empathy for this value
is to adjust valueanimator animator = Valueanimator.offloat (MAXELASTICFACTOR/4, (float) (Maxelasticfactor/ 1.5), 0);
Animator.setduration (DURATION/2);
Animator.addupdatelistener (New Valueanimator.animatorupdatelistener () {
@Override public
Void Onanimationupdate (Valueanimator animation) {
calc ();//Redraw path
nowelasticfactor= (float) Animation.getanimatedvalue ();
Postinvalidate ();
}
);
Animator.start ();
}

One more way to paint the path calculation

public void Calc () {
//reset Path
path.reset ();
Since the drawing text is started by the baseline
Path.moveto (Iv.getx ()-textwidth/2+iv.getwidth ()/2, textheight+iv.getheight () +downheight* Iv.getheight ());
Draw two Bezier curves
path.rquadto (TEXTWIDTH/2, Nowelasticfactor, textWidth, 0);

OK, let's take a look at the complete source code:

Package com.example.administrator.myapplication;
Import Android.animation.ObjectAnimator;
Import Android.animation.ValueAnimator;
Import Android.content.Context;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.graphics.Path;
Import Android.graphics.Rect;
Import Android.util.AttributeSet;
Import Android.view.ViewGroup;
Import Android.view.ViewTreeObserver;
Import Android.view.animation.AccelerateInterpolator;
Import android.view.animation.Animation;
Import Android.view.animation.DecelerateInterpolator;
Import android.view.animation.TranslateAnimation;
Import Android.widget.FrameLayout;
Import Android.widget.ImageView; public class My extends Framelayout {//brush private Paint Paint;//path private path path;//text to enter private String Printtext
= "Loading";
Text wide private float textWidth;
Text high private float textHeight;
When measuring the width of the text, use the rectangle private Rect Rect;
Maximum elasticity coefficient private float elastic = 1.5f;
Maximum elasticity private float maxelasticfactor; CurrentElastic private float Nowelasticfactor;
Used to record the current picture using which int indeximgflag = 0 in the array;
Sinking picture int Allimgdown [] = {R.MIPMAP.P2,R.MIPMAP.P4,R.MIPMAP.P6,R.MIPMAP.P8};
Animation effect a sinking or bouncing time animationduration*2= a full animation time int animationduration = 1000;
Bouncing pictures of ImageView IV;
Picture sinking height (i.e. distance from highest to lowest point) int downheight = 2;
Private Animation Translatedown;
Private Animation Translateup;
Private Objectanimator rotation; Public I (context) {Super [context];} public I (context, AttributeSet attrs) {Super (context, attrs);} Override protected void Dispatchdraw (Canvas Canvas) {Super.dispatchdraw (Canvas); Canvas.drawtextonpath (Printtext,
Path, 0, 0, paint);
}//For playing text sinking and floating animation the incoming value must be a time when the picture sinks and rises public void initanimation (int duration) {//here why MAXELASTICFACTOR/4
Valueanimator animator = Valueanimator.offloat (MAXELASTICFACTOR/4, (float) (maxelasticfactor/1.5), 0);
Animator.setduration (DURATION/2); Animator.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void OnanimatioNupdate (Valueanimator animation) {calc (); nowelasticfactor= (float) animation.getanimatedvalue (); Postinvalidate ();}})
;
Animator.start (); The public void Calc () {//reset path Path.reset ();//As the drawing text is started by the baseline Path.moveto (Iv.getx ()-textwidth/2+iv.getwidth ()/2,
Textheight+iv.getheight () +downheight*iv.getheight ());
Draw two times Bezier curve path.rquadto (TEXTWIDTH/2, Nowelasticfactor, textWidth, 0); }//Initialize bounce animation public void Myanmation () {//sinking effect Animation Translatedown = new Translateanimation (animation.relative_to_self,0,
animation.relative_to_self,0, Animation.relative_to_self,0,animation.relative_to_self,downheight);
Translatedown.setduration (animationduration);
Setting an interpolation animation will play more and more quickly to simulate gravity translatedown.setinterpolator (new Accelerateinterpolator ());
Up animation translateup = new Translateanimation (animation.relative_to_self,0,animation.relative_to_self,0,
animation.relative_to_self,downheight,animation.relative_to_self,0);
Translateup.setduration (animationduration); Setting an interpolation animation will play more and more slowly analog anti-gravity Translateup.setinterpolator (nEW Decelerateinterpolator ()); Play Boot Translatedown.setanimationlistener (new Animation.animationlistener () {@Override public void when the sinking animation completes Onanimationstart (Animation Animation) {Iv.setimageresource (Allimgdown[indeximgflag]); rotation =
Objectanimator.offloat (iv, "rotation", 180f, 360f);
Rotation.setduration (1000);
Rotation.start (); @Override public void Onanimationend (Animation Animation) {iv.startanimation (translateup); Initanimation (
Animationduration);
@Override public void Onanimationrepeat (Animation Animation) {}}); Plays the move down animation Translateup.setanimationlistener when the move animation completes (new Animation.animationlistener () {@Override public void
Onanimationstart (Animation Animation) {Indeximgflag = 1+indeximgflag>=allimgdown.length?0:1+indeximgflag;
Iv.setimageresource (Allimgdown[indeximgflag]);
rotation = Objectanimator.offloat (iv, "rotation", 0.0f, 180f);
Rotation.setduration (1000);
Rotation.start (); @Override public void Onanimationend (Animation Animation) {//recursive iv.startanimation (transLatedown);
@Override public void Onanimationrepeat (Animation Animation) {}});
Boolean flagmeure;
@Override protected void onsizechanged (int w, int h, int oldw, int oldh) {super.onsizechanged (W, H, OLDW, OLDH); init ();
} private void Init () {//Initialize bounce Picture Control IV = New ImageView (GetContext ());
Viewgroup.layoutparams params = new Viewgroup.layoutparams (ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Iv.setlayoutparams (params);
Iv.setimageresource (Allimgdown[0]);
This.addview (iv);
The initialization of the brush paint = new paint ();
Paint.setstrokewidth (1);
Paint.setcolor (Color.cyan);
Paint.setstyle (Paint.Style.FILL);
Paint.settextsize (50);
Paint.setantialias (TRUE);
Rectangular rect = new rect ();
The purpose of drawing text into the rectangle is to measure height paint.gettextbounds (printtext, 0, Printtext.length (), rect);
Text width textWidth = paint.measuretext (Printtext);
Get text Height textHeight = rect.bottom-rect.top;
Initializes path PATH = new Path ();
Iv.setx (GetWidth ()/2);
Iv.measure (0,0); Iv.getviewtreeobserver (). Addongloballayoutlistener (NewViewtreeobserver.ongloballayoutlistener () {@Override public void Ongloballayout () {if (!flagmeure) {flagmeure =true;// Since the drawing text is started by the baseline Path.moveto (Iv.getx ()-textwidth/2+iv.getwidth ()/2, textheight+iv.getheight () +downheight*
Iv.getheight ());
Calculate Maximum Elastic Maxelasticfactor = (float) (textheight/elastic);
Initialize Bezier curves path.rquadto (TEXTWIDTH/2, 0, textWidth, 0);
Initialize the up and down animation myanmation ();
Iv.startanimation (Translatedown);
}
}
}); }
}

Villain to the source of a letter for everyone to reference github source download address

The above is a small set to introduce the Android custom view to achieve the damping effect of the load animation, 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!

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.