Android ListView Drop-down Refresh pull automatically load more demo samples _android

Source: Internet
Author: User
Tags gety

The code download address has been updated. Because the code is not updated for a long time, has been very outdated, we recommend the use of Recyclerview implementation.

Reference items:

Https://github.com/bingoogolapple/BGARefreshLayout-Android

Https://github.com/baoyongzhang/android-PullRefreshLayout

Drop-down refresh, a very common feature of Android. In order to facilitate the rewrite of the ListView to achieve Drop-down refresh, while adding a pull to automatically load more features. Originally designed to refer to open source China's Android client source. Look at the sample diagram first.

Figure 1 Figure 2


Figure 3 Figure 4


Figure 5 Figure 6

Drop-down Refresh when the animation effect: Figure 1 = = "Figure 2 =" Figure 3 = "Figure 4 = =" Figure 1.

Pull automatically load more effects: Figure 5

Figure 6 is a screenshot of the example demo

After the overridden ListView animation effect originates from the added header and tail (footer), ListView provides Addheaderview and Addfooterview methods to add headers and footer. You can also define your own animation effects by modifying the header and tail XML files.

Implementation principle

1. Drop Down Refresh

Change the header of the ListView by ontouchevent the gesture of judgment. The header has a total of 4 states, defined by itself as:

NONE (corresponding to Figure 1): initial state

PULL (corresponding to Figure 2): dropdown state, at this time loose meeting restore to state None, not to refresh

Release (corresponding to Figure 3): The same is the Drop-down state, but now loosen will perform the refresh, enter the state refreshing

Refreshing (corresponding to Figure 4): Performing a refresh and entering the status after the refresh is complete none.

The header changes not only the internal component but also its size in four state transitions. Change the internal components of the embodiment, for example, the arrow is facing up or down, the text prompts the change, waiting for the circle to display or not. The change in size is a change in height, and the height of the header when the header height is 0,release is determined by the degree of the drop.

2. Load more

After the ListView slide stops, determine if the last item of the ListView has been shown, and if the display shows that ListView has slipped to the bottom, then it triggers more methods to load, and the method ends by changing the footer according to the result.

3. Callback method

Two interfaces Onrefreshlistener and Onloadlistener are defined in the class to define and provide methods for loading data, and implementation is given to their implementation classes.

Package com.example.autolistview.widget; 
Import COM.EXAMPLE.AUTOLISTVIEW.R; 
Import Com.example.autolistview.utils.Utils; 
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.LinearInterpolator; 
Import android.view.animation.RotateAnimation; 
Import Android.widget.AbsListView; 
Import Android.widget.ImageView; 
Import Android.widget.ProgressBar; 
Import Android.widget.TextView; 
Import Android.widget.AbsListView.OnScrollListener; 
Import Android.widget.ListView; /** * @author Sunnycoffee * @create 2013-10-24 * @version 1.0 * @desc custom listview Drop-down Refresh, pull load more/public class Autoli 
Stview extends ListView implements Onscrolllistener {//distinguish whether the current operation is refreshing or loading public static final int refresh = 0; 
public static final int LOAD = 1; 
The size of the distance between pull and release. private static final int space = 20; Defines four states and current states of the header
private static final int NONE = 0; 
private static final int PULL = 1; 
private static final int release = 2; 
private static final int refreshing = 3; 
private int state; 
Private Layoutinflater Inflater; 
Private View header; 
Private View footer; 
Private TextView tip; 
Private TextView lastupdate; 
Private ImageView Arrow; 
Private ProgressBar refreshing; 
Private TextView NoData; 
Private TextView Loadfull; 
Private TextView more; 
private ProgressBar loading; 
Private rotateanimation animation; 
Private Rotateanimation reverseanimation; 
private int starty; 
private int firstvisibleitem; 
private int scrollstate; 
private int headercontentinitialheight; 
private int headercontentheight; 
Only when the first item is displayed (ListView slide to the top) to pull the refresh, otherwise at this time the drop is just sliding listview private Boolean isrecorded listview; 
Private Boolean isloading;//to determine whether the private Boolean loadenable = true;//is being loaded to turn on or off load more features private Boolean isloadfull; 
private int pageSize = 10; 
Private Onrefreshlistener Onrefreshlistener; PriVate Onloadlistener Onloadlistener; 
Public Autolistview {Super (context); 
Initview (context); 
Public Autolistview (context, AttributeSet attrs) {Super (context, attrs); 
Initview (context); 
Public Autolistview (context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle); 
Initview (context); }//Drop-down refresh listener public void Setonrefreshlistener (Onrefreshlistener onrefreshlistener) {This.onrefreshlistener = OnRefreshL 
Istener; 
}//load more listener public void Setonloadlistener (Onloadlistener onloadlistener) {this.loadenable = true; 
This.onloadlistener = Onloadlistener; 
public Boolean isloadenable () {return loadenable; 
}//Here the turn on or off load more, does not support dynamic adjustment of the public void Setloadenable (Boolean loadenable) {this.loadenable = loadenable; 
This.removefooterview (footer); 
public int getpagesize () {return pageSize; 
The public void setpagesize (int pageSize) {this.pagesize = pageSize; }//Initialize component private void Initview (context context) {//Set Arrow Effects animation = new Rotateanimation (0, -180, rotateanimation.relative_to_self, 0.5f, rotateanimation.relative_to_s 
ELF, 0.5f); 
Animation.setinterpolator (New Linearinterpolator ()); 
Animation.setduration (100); 
Animation.setfillafter (TRUE); Reverseanimation = new Rotateanimation ( -180, 0, Rotateanimation.relative_to_self, 0.5f, rotateanimation.relative_to_ 
SELF, 0.5f); 
Reverseanimation.setinterpolator (New Linearinterpolator ()); 
Reverseanimation.setduration (100); 
Reverseanimation.setfillafter (TRUE); 
Inflater = Layoutinflater.from (context); 
Footer = inflater.inflate (r.layout.listview_footer, NULL); 
Loadfull = (TextView) Footer.findviewbyid (r.id.loadfull); 
NoData = (TextView) Footer.findviewbyid (r.id.nodata); 
more = (TextView) Footer.findviewbyid (R.id.more); 
Loading = (ProgressBar) Footer.findviewbyid (r.id.loading); 
Header = Inflater.inflate (R.layout.pull_to_refresh_header, NULL); 
Arrow = (ImageView) Header.findviewbyid (R.id.arrow); tip = (TextView) Header.findviewbyid(R.id.tip); 
Lastupdate = (TextView) Header.findviewbyid (r.id.lastupdate); 
refreshing = (ProgressBar) Header.findviewbyid (r.id.refreshing); 
Add the head and tail to the ListView and Initialize Headercontentinitialheight = Header.getpaddingtop (); 
Measureview (header); 
Headercontentheight = Header.getmeasuredheight (); 
TopPadding (-headercontentheight); 
This.addheaderview (header); 
This.addfooterview (footer); 
This.setonscrolllistener (this); 
public void Onrefresh () {if (Onrefreshlistener!= null) {Onrefreshlistener.onrefresh (); 
} public void OnLoad () {if (Onloadlistener!= null) {onloadlistener.onload (); }} public void Onrefreshcomplete (String updatetime) {Lastupdate.settext (This.getcontext (). GetString ( 
R.string.lastupdatetime, lastupdate)); 
state = NONE; 
Refreshheaderviewbystate (); 
//Callback public void Onrefreshcomplete () {String currenttime = Utils.getcurrenttime () for Drop-down refresh end; 
Onrefreshcomplete (currenttime); //is used to load more closed callbacks public void Onloadcomplete () {isloading = false; 
@Override public void Onscroll (Abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { 
This.firstvisibleitem = Firstvisibleitem; 
@Override public void onscrollstatechanged (Abslistview view, int scrollstate) {this.scrollstate = scrollstate; 
Ifneedload (view, scrollstate);  
////According to the ListView sliding state to determine whether more private void ifneedload (Abslistview view, int scrollstate) {if (!loadenable) {return is required to be loaded; try {if (scrollstate = Onscrolllistener.scroll_state_idle &&!isloading && View.getlastvisiblepo 
Sition () = = view. Getpositionforview (footer) &&!isloadfull) {onLoad (); 
IsLoading = true;  The catch (Exception e) {}}/** * listens for touch events, interprets gestures */@Override public boolean ontouchevent (motionevent ev) {switch (Ev.getaction ()) 
{case MotionEvent.ACTION_DOWN:if (Firstvisibleitem = = 0) {isrecorded = true; 
Starty = (int) ev.gety (); 
} break; Case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:if (state = =PULL) {state = NONE; 
Refreshheaderviewbystate (); 
else if (state = = release) {state = refreshing; 
Refreshheaderviewbystate (); 
Onrefresh (); 
} isrecorded = false; 
Break 
Case MotionEvent.ACTION_MOVE:whenMove (EV); 
Break 
return super.ontouchevent (EV); 
}//Read gesture, refresh header status private void Whenmove (Motionevent ev) {if (!isrecorded) {return; 
int tmpy = (int) ev.gety (); 
int space = Tmpy-starty; 
int toppadding = Space-headercontentheight; 
Switch (state) {case none:if (Spaces > 0) {state = PULL; 
Refreshheaderviewbystate (); 
} break; 
Case Pull:toppadding (toppadding); 
if (scrollstate = = Scroll_state_touch_scroll && space > headercontentheight + spaces) {state = release; 
Refreshheaderviewbystate (); 
} break; 
Case Release:toppadding (toppadding); 
if (Space > 0 && Spaces < Headercontentheight + spaces) {state = PULL; 
Refreshheaderviewbystate (); 
else if (space <= 0) {state = NONE; 
Refreshheaderviewbystate (); } 
Break //Adjusts the header size. 
In fact, the adjustment is only the height from the top. 
private void toppadding (int toppadding) {header.setpadding (Header.getpaddingleft (), toppadding, 
Header.getpaddingright (), Header.getpaddingbottom ()); 
Header.invalidate (); 
/** * This method is based on the size of the result to determine the footer display. * <p> * This assumes that the number of bars per request is 10. If the request to 10. Think there is still data. If the result is less than 10, then the data has been fully loaded, then footer display has been fully loaded * </p> * * @param resultsize/public void setresultsize (int resultsize 
{if (resultsize = = 0) {Isloadfull = true; 
Loadfull.setvisibility (View.gone); 
Loading.setvisibility (View.gone); 
More.setvisibility (View.gone); 
Nodata.setvisibility (view.visible); 
else if (resultsize > 0 && resultsize < pageSize) {isloadfull = true; 
Loadfull.setvisibility (view.visible); 
Loading.setvisibility (View.gone); 
More.setvisibility (View.gone); 
Nodata.setvisibility (View.gone); 
else if (resultsize = = pageSize) {isloadfull = false; 
Loadfull.setvisibility (View.gone); 
Loading.setvisibility (view.visible); More.setvisibility(view.visible); 
Nodata.setvisibility (View.gone); }///According to current state, adjust header private void refreshheaderviewbystate () {switch (state) {Case none:toppadding (-headerconte 
Ntheight); 
Tip.settext (R.string.pull_to_refresh); 
Refreshing.setvisibility (View.gone); 
Arrow.clearanimation (); 
Arrow.setimageresource (R.drawable.pull_to_refresh_arrow); 
Break 
Case PULL:arrow.setVisibility (view.visible); 
Tip.setvisibility (view.visible); 
Lastupdate.setvisibility (view.visible); 
Refreshing.setvisibility (View.gone); 
Tip.settext (R.string.pull_to_refresh); 
Arrow.clearanimation (); 
Arrow.setanimation (reverseanimation); 
Break 
Case RELEASE:arrow.setVisibility (view.visible); 
Tip.setvisibility (view.visible); 
Lastupdate.setvisibility (view.visible); 
Refreshing.setvisibility (View.gone); 
Tip.settext (R.string.pull_to_refresh); 
Tip.settext (R.string.release_to_refresh); 
Arrow.clearanimation (); 
Arrow.setanimation (animation); 
Break 
Case Refreshing:toppadding (headercontentinitialheight); REfreshing.setvisibility (view.visible); 
Arrow.clearanimation (); 
Arrow.setvisibility (View.gone); 
Tip.setvisibility (View.gone); 
Lastupdate.setvisibility (View.gone); 
Break To calculate the header size. 
More obscure. 
private void Measureview (View child) {Viewgroup.layoutparams P = child.getlayoutparams (); if (p = = null) {p = new Viewgroup.layoutparams (ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTEN 
T); 
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 {childheightspec = Measurespec.makemeasurespec (0, measurespec.unspecified); 
} child.measure (Childwidthspec, Childheightspec); 
/* * Define DROP-DOWN Flush Interface * * * public interface Onrefreshlistener {public void Onrefresh (); 
* * * Definition Load More interface */public interface Onloadlistener {public void onLoad (); } 
}

The logical complexity of this class is the determination and switching of header four states.

Here are the transitions for several states

NONE = "PULL
NONE "= = PULL =" Release
PULL "= = Release = =" refreshing
refreshing = "NONE"

In the code for release = = "PULL State of the switch processing is not ideal, as if the ordinate record way there is a problem, if there is a solution, hope to be able to leave a message to inform."

To reduce space, the rest of the code is not posted.

Note: The XML outermost layer that defines the header must use a linear layout, otherwise there will be an error.

The above is a small set to introduce the Android ListView Drop-down Refresh pull automatically load more demo example, 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.