Android imitation Baidu takeout custom pull down refresh effect _android

Source: Internet
Author: User
Tags gety

Today's variety of apps, also brought a variety of needs, a drop-down refresh can play a pattern, the first two days when the meal was inadvertently seen the "Baidu Takeaway" Drop-down refresh, today's theme is it-custom Drop-down refresh animation.

Take a look at the implementation effect bar:


Animation

Let's take a look at the animations in Android:

The animations in Android are divided into three types:

Tween animation, this kind of animation provides the rotation, translation, scaling and other effects.

alpha– Fade in Fade

scale– Scaling Effect

roate– Rotation effect

translate– Translation Effect

Frame animation (frame animation), which allows you to create a drawable sequence that is displayed one at a time in a specified interval.

Property Animation (property animation), which is the Android3.0 of an attribute animation that changes the actual properties of an object.

Analysis

We can see the Baidu takeaway drop to refresh the head is a cycling courier on the road, analysis we get the following animation:

Translation animation of background picture

Self-rotating animation of the sun

Self-rotating animation of two small wheels

This is very simple, then we go to Baidu outside the picture resources file found in these several pictures: (download Baidu apk direct decompression can be)


Definition dropdown flush header file: Headview.xml

Notice here: We have defined the ImageView of two background images in order to achieve the translation animation effect of the background.

<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android= "http://schemas.android.com/apk/res/" Android "android:orientation=" vertical "android:layout_width=" match_parent "android:layout_height=" Wrap_content " > <imageview android:id= "@+id/iv_back1" android:src= "@drawable/pull_back" android:layout_width= "match_parent
"android:layout_height=" 100DP "/> <imageview android:id=" @+id/iv_back2 "android:src=" @drawable/pull_back "
Android:layout_width= "Match_parent" android:layout_height= "100DP"/> <relativelayout android:id= "@+id/main" Android:layout_centerhorizontal= "true" android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" > <imageview android:layout_margintop= "45DP" android:id= "@+id/iv_rider" android:background= "@drawable/pull_ Rider "android:layout_width=" 50DP "android:layout_height=" 50DP "/> <imageview android:id=" @+id/wheel1 "Android : layout_marginleft= "10DP" android:layout_margintop= "90DP" android:background= "@drawable/pull_wheel "android:layout_width=" 15DP "android:layout_height=" 15DP "/> <imageview android:id=" @+id/wheel2 "
android:layout_marginleft= "40DP" android:layout_margintop= "90DP" android:background= "@drawable/pull_wheel" Android:layout_width= "15DP" android:layout_height= "15DP"/> </RelativeLayout> <imageview android:id= "@+" Id/ivsun "android:layout_margintop=" 20DP "android:layout_torightof=" @+id/main "android:background=" @drawable/pull _sun "android:layout_width=" 30DP "android:layout_height=" 30DP "/> </RelativeLayout>

Next we define the animation effect:

Translation effect of background picture:

Implements two animation XML files, one starting position in 100%, ending position at 0%, and setting repeat property to cycle.

<?xml version= "1.0" encoding= "Utf-8"?> <set xmlns:android=
"http://schemas.android.com/apk/res/" Android "Android:interpolator=" @android: Anim/accelerate_interpolator ">
<translate android:fromxdelta=" 100%p "Android:toxdelta=" 0%p "
android:repeatmode=" restart "
android:interpolator=" @android: Anim/linear_ Interpolator "
android:repeatcount=" Infinite "
android:duration=" 5000 "/>
</set>

Another starting position at 0%, end position at-100%

<?xml version= "1.0" encoding= "Utf-8"?> <set xmlns:android=
"http://schemas.android.com/apk/res/" Android "Android:interpolator=" @android: Anim/accelerate_interpolator ">
<translate android:fromxdelta=" 0%p "Android:toxdelta=" -100%p "
android:repeatmode=" restart "
android:interpolator=" @android: Anim/linear_ Interpolator "
android:repeatcount=" Infinite "
android:duration=" 5000 "/>
</set>

The Sun rotates around the center of the animation:

Starting at 0-360 degrees, the rotation time is 1s, and the center of rotation is 50% distance from the left point of view, which is the positive center.

The following are the specific attributes:

Android:fromdegrees Starting angle Degree

Android:todegrees the angle of the end, negative numbers are counterclockwise, positive numbers are clockwise. If 10 laps is bigger than android:fromdegrees 3600 can

X-coordinate of Android:pivotx rotation center

Floating-point number or percent. The floating-point number represents the left edge relative to object, such as 5; The percentage is expressed relative to the left edge of object, such as 5%; Another percentage indicates the relative to the left edge of the parent container, such as 5%p; A general setting of 50% means the object center

The y-coordinate of the Android:pivoty rotation Center

Floating-point number or percent. A floating-point number represents the upper edge of object, such as 5; The percentage is expressed relative to the top edge of object, such as 5%; Another percentage represents the upper edge of the parent container, such as 5%p; A general setting of 50% means the object center

Android:duration represents the amount of time spent in milliseconds to rotate from android:fromdegrees to android:todegrees. can be used to calculate speed.

Android:interpolator represents the rate of change, but not the speed at which it is run. A interpolation property, you can set the animation effect to speed, deceleration, repetition, bounce and so on. The default is start and end slow middle fast,

Android:startoffset the time after the start function is called, in milliseconds, or 10, to start running after 10ms

Android:repeatcount the number of repetitions, the default is 0, must be int, can be-1 means not to stop

Android:repeatmode repeat mode, default to restart, that is, start over again, can be reverse that is, from the end of the run forward again. Effective when Android:repeatcount is greater than 0 or infinite

Android:detachwallpaper indicates whether to run on the wallpaper

Android:zadjustment represents the position of the animated content at run time on the z-axis, which defaults to normal.

Normal retains the current z-axis order of content

Top run is displayed at the topmost level

Bottom runtime display at the bottom

<?xml version= "1.0" encoding= "Utf-8"?> <set xmlns:android=
"http://schemas.android.com/apk/res/" Android ">
<rotate
android:fromdegrees=" 0 "
android:todegrees=" 360 "
android:duration=" 1000 "
android:repeatcount="-1 "
android:pivotx=" 50% "
android:pivoty=" 50% "/>
</set>

The same is also the case for the same wheel animation, not the code.

Definition of animation We start to define Drop-down refresh list, drop-down refresh online There are a lot of, not in detail, the simple transformation, according to the state of refresh to turn off animation.

Note written in detail, take a look at the code:

Package com.hankkin.baidugoingrefreshlayout;
Import Android.widget.AbsListView;
Import Android.widget.ListView;
Import Android.content.Context;
Import Android.util.AttributeSet;
Import Android.view.LayoutInflater;
Import android.view.MotionEvent;
Import Android.view.View;
Import Android.view.ViewGroup;
Import android.view.animation.Animation;
Import Android.view.animation.AnimationUtils;
Import Android.widget.ImageView;
Import Android.widget.RelativeLayout;
/** * Created by Hankkin on 16/4/10. */public class Baidurefreshlistview extends ListView implements abslistview.onscrolllistener{private static final int do NE = 0; Refresh complete State private static final int pull_to_refresh = 1; Drop-down Refresh status private static final int release_to_refresh = 2; Free State private static final int refreshing = 3;
Refreshing state private static final int RATIO = 3; Private Relativelayout Headview; Dropdown flush Head private int headviewheight; Head height private float starty; Start y-coordinate private float offsetY; Y-axis offset private OnbaidurefreshlistenER monrefreshlistener; Flush interface private int state; State value private int mfirstvisibleitem; The first item is visible on the item index private Boolean IsRecord; Whether to record private Boolean isend; Whether to end private Boolean isrefreable; Whether to refresh private ImageView Ivwheel1,ivwheel2; Wheel Group picture components private ImageView ivrider; Rider Picture Component Private ImageView Ivsun,ivback1,ivback2; Sun, background picture 1, background picture 2 private Animation wheelanimation,sunanimation; Wheel, Sun animation private Animation Backanimation1,backanimation2; Two background images animation public Baidurefreshlistview (context) {super (contexts); init (contextual);} Public Baidurefreshlistview ( Context context, AttributeSet Attrs) {Super (context, attrs); init (context); \ public Baidurefreshlistview (context Contex T, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr); init (context); \ public interface Onbaidur efreshlistener{void Onrefresh ();/** * Callback interface to implement this interface * @param onrefreshlistener/public void Setonbaidur Efreshlistener (Onbaidurefreshlistener onrefreshlistener) {monrefreshlistEner = Onrefreshlistener;
Isrefreable = true;
/** * Refresh complete, from the main line Cheng sent over, and change the state of Headerview and text animation information/public void Setonrefreshcomplete () {//Make sure to set Isend to true so that the next Drop-down refresh
Isend = true;
state = done;
Changeheaderbystate (state); } private void Init (context context) {//Close view's Overscroll Setoverscrollmode (over_scroll_never); Setonscrolllistener (
this);
Load Header Layout Headview = (relativelayout) layoutinflater.from (context). Inflate (R.layout.headview,this,false);
Measuring head layout Measureview (Headview);
Add header Layout Addheaderview (Headview) to ListView;
The set header file is hidden in the first item of the ListView Headviewheight = Headview.getmeasuredheight ();
Headview.setpadding (0,-headviewheight, 0, 0);
Get header layout Picture component Ivrider = (ImageView) Headview.findviewbyid (R.id.iv_rider);
Ivsun = (ImageView) Headview.findviewbyid (R.id.ivsun);
IvWheel1 = (ImageView) Headview.findviewbyid (R.ID.WHEEL1);
IvWheel2 = (ImageView) Headview.findviewbyid (R.ID.WHEEL2);
IvBack1 = (ImageView) Headview.findviewbyid (R.ID.IV_BACK1); IvBack2 = (ImageView) Headview.findviewbyid (R.ID.IV_BACK2);
Get animation wheelanimation = animationutils.loadanimation (context, r.anim.tip);
Sunanimation = animationutils.loadanimation (context, R.ANIM.TIP1);
BackAnimation1 = animationutils.loadanimation (context, R.ANIM.A);
BackAnimation2 = animationutils.loadanimation (context, R.ANIM.B);
state = done;
Isend = true;
Isrefreable = false; @Override public void onscrollstatechanged (Abslistview abslistview, int i) {} @Override public void Onscroll (Abslistvie W abslistview, int firstvisibleitem, int visibleitemcount, int totalitemcount) {mfirstvisibleitem = Firstvisibleitem;} @ Override public boolean ontouchevent (motionevent ev) {if (isend) {//If the current end state, that is, the refresh is complete, you can refresh again, set the IF in the Onrefreshcomplete (isrefreable) {//If it is now a refreshed state in Setonmeituanlistener set to True switch (Ev.getaction ()) {//user presses case Motionevent.action_down:// If you are currently at the top of the ListView and there is no record y-coordinate if (Mfirstvisibleitem = = 0 &&!isrecord) {//IsRecord to True, the Y coordinate IsRecord = true is now logged
;
Assigns the current Y coordinate to the starty starting y-coordinate starty = Ev.gety ();
} break; User Sliding case MotIonevent.action_move://Get Y coordinate again, use to subtract with starty to calculate offsety displacement value float tempy = ev.gety (); Again to determine if it is the top of the ListView and there is no record y-coordinate if (Mfirstvisibleitem = = 0 &&!isrecord) {IsRecord = true; starty = Tempy;}//If The former state is not a state that is being refreshed, and the y-coordinate if (state!=refreshing && isrecord) {//y offset OffsetY = tempy-starty;//Calculate the height of the current slide is recorded Floa
T currentheight = (-HEADVIEWHEIGHT+OFFSETY/3);
Using the current sliding height and the total height of the head headerview to calculate the current sliding percentage of 0 to 1 float currentprogress = 1+currentheight/headviewheight; If the current percentage is greater than 1, set it to 1, so that the ellipse of the first state no longer continues to be larger if (currentprogress>=1) {currentprogress = 1;}//If the current state is open flush and the y-coordinate is logged if (state = = Release_to_refresh && isrecord)
REFRESH;
Change the Headerview according to the state, mainly update the information such as animation and text changeheaderbystate. If the current Y displacement value is less than 0, then the Headerview hides the}else if (offsety<=0) {//changes the state to done states = done; Stopanim ();///change according to state Headerview,
Mainly updates the animation and text and other information changeheaderbystate (state); }//IfThe current state is a drop-down refresh and the y-coordinate has been recorded for the Pull_to_refresh && isrecord {setselection (0);//If the drop distance is greater than or equal to the total height of Headerview if (h
eadviewheight+offsety/ratio>=0) {///change the state to a release-refresh states = Release_to_refresh///////depending on the status Headerview, mainly update the animation and text information
Changeheaderbystate (state);
If the current Y displacement value is less than 0, then the Headerview hides the}else if (offsety<=0) {//The State is done as done;
Changeheaderbystate (state); }///If the current status is done and the y-coordinate is already logged (state = && IsRecord) {//If the displacement value is greater than 0 if (offsety>=0) {//change the state to a drop-down refresh state =
Pull_to_refresh;
Changeheaderbystate (state); }//If the Drop-down refresh status if (state = = Pull_to_refresh) {//is changed Headerview padding to achieve the pull effect headview.setpadding (0, (int) (-
Headviewheight+offsety/ratio), 0,0); //If you are releasing the refresh status if (state = = Release_to_refresh) {//changing Headerview padding value headview.setpadding (0, (int) (-headviewheight+
Offsety/ratio), 0, 0);
}} break;
Case MOTIONEVENT.ACTION_UP When the user's finger is raised://If the current state is a drop-down refresh status if (state = = Pull_to_refresh) {//Smooth hide Headerview This.smoothscrollby ((int) (-Headviewheight+offsety/ratio) +headviewheight, 500);
Change Headerview changeheaderbystate (state) according to condition; //If the current state is open to refresh if (= = = Release_to_refresh) {//smooth slide to show Headerview This.smoothscrollby (int) (-headviewheight+
Offsety/ratio), 500);
Sets the current state to being refreshed by = refreshing;
The Onrefresh method of the callback interface Monrefreshlistener.onrefresh ();
Change Headerview changeheaderbystate (state) according to condition;
//This set of gestures is done, don't forget to change the isrecord of the record Y coordinate to false so that the next gesture IsRecord = false;
Break
}} return super.ontouchevent (EV); /** * Headerview Animation and text display based on status * @param state */private void changeheaderbystate (int state) {switch
://If the hidden state//set Headerview padding for hidden headview.setpadding (0,-headviewheight, 0, 0);
Startanim ();
Break
Case release_to_refresh://Current state for release refresh break;
Case pull_to_refresh://The current state is a drop-down refresh Startanim ();
Break
Case refreshing://The current state is refreshing the break;
Default:break; }/** * Measuring view * @param child/private void Measureview (view child) {Viewgroup.layoutparams p = child.getlayoutparams
(); if (p = = null) {
p = new Viewgroup.layoutparams (ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
int childwidthspec = viewgroup.getchildmeasurespec (0, 0 + 0, p.width);
int lpheight = P.height;
int childheightspec; if (Lpheight > 0) {childheightspec = Measurespec.makemeasurespec (Lpheight, measurespec.exactly);} else {ChildHeightS
PEC = Measurespec.makemeasurespec (0, measurespec.unspecified);
} child.measure (Childwidthspec, Childheightspec); /** * Open animation/public void Startanim () {ivback1.startanimation (backAnimation1); Ivback2.startanimation (BackAnimation2)
;
Ivsun.startanimation (sunanimation);
Ivwheel1.startanimation (wheelanimation);
Ivwheel2.startanimation (wheelanimation); /** * Close animation/public void Stopanim () {ivback1.clearanimation (); Ivback2.clearanimation (); Ivsun.clearanimation (); ivWhe
El1.clearanimation ();
Ivwheel2.clearanimation (); }
}

OK, the custom Drop-down refresh animation We have achieved, in fact, is very simple, all the Drop-down Flash animation is similar to this implementation. The source code I have uploaded to the github:

Https://github.com/Hankkin/BaiduGoingRefreshLayout

Please, star. There are unreasonable places also hope that everyone to correct, common progress ha.

About Android imitation Baidu outside the definition of a custom pull refresh effect, small set to introduce to everyone here, I hope to help you!

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.