Android ListView Dropdown/Pull-up refresh: design principle and implementation

Source: Internet
Author: User



"Android ListView dropdown/Pull-up refresh: Design principles and Implementation"

Android on the ListView third party open-source drop-down refresh frame a lot, the application scenario is very common, almost become the general design of the app now, even Google officially support at the Android SDK level pull refresh, I wrote an article "Android Swiperefreshlayout: The drop-down refresh in Google's official SDK package (link address: http://blog.csdn.net/zhangphil/article/details/46965377).
Each ListView dropdown refreshes the Open source framework, the basic functions are the same, the design principle is similar, the function of the pull-down refresh, one of the design implementation of the core points of the program is mostly focused on the Onscrolllistener () and other events such as the ListView. However, some of the common drop-down refreshes in the open source framework, some lack of pull-up refresh functionality. The pull-up refresh feature is also needed in some scenarios, such as when the user's device screen is loaded from the network due to the data, but once the network request is not able to load all the data at all, it feeds only a subset of the data in the initialization phase. When the user turns to the bottom of a ListView, "load more", note! Here is another design, such as in the ListView footer View Design a button, assuming that the button is called "Load more", when the user turned to the end of the ListView, click on the button to "load more" again to launch data request load more data, And then refresh the ListView, this design is also more common. This article describes a ListView that can automatically sense the ListView drop-down, and then automatically load more support for pull-up/pull-up refreshes.

A: Overview of Design principles:

Because we want to design and implement the pull-down and pull-up refreshes at the same time, obviously, we can't just do the pull-down refresh function, but also do the pull-up refresh function. The drop-down refresh and the gesture direction of the pull-up refresh are different (the opposite), so the first thing we need to do is to put both of these cases (whether the user's intention is to drop the peak refresh or the pull-up bottom refresh?). ) to differentiate it.
To achieve this, we monitor the Ontouch () event in the ListView and then use Gesturedetector to determine whether the user's finger is moving up or down on the screen, thus clarifying the user's intention in the end to pull the peak (top, The first item of the ListView, numbered 0) is refreshed or pulled up at the bottom (bottom, one of the last and most trailing elements of the ListView).
When we know the user's intentions (drop-down peak refresh, or, pull-up bottoming refresh). Then calculate and analyze: The first element (Firstvisibleitem) of the current ListView in the visible area of the screen, the number of elements of the ListView within the visible area (visibleitemcount), The number of the three elements of the ListView (Totalitemcount). Simply put, when firstvisibleitem==0 and the user is down, the code thinks the user's intention is to pull the refresh; when Firstvisibleitem + VisibleItemCount = = Totalitemcount, The code thinks the user's intention is to pull up the refresh.
Where Firstvisibleitem, VisibleItemCount, totalitemcount values can be updated from the Onscrolllistener of the ListView.

B: Realization of design principle:

(1th Step) to the ListView Setonscrolllistener, overriding the Onscrolllistener Onscroll method in the ListView, with the aim of updating Firstvisibleitem in real time, VisibleItemCount, Totalitemcount value.
(2nd Step): Every Android ListView inherits from Android View,android View has one:
public void Setontouchlistener (View.ontouchlistener l);

We pass this method to a view.ontouchlistener, and then rewrite the View.ontouchlistener inside:
Public abstract Boolean OnTouch (View V, motionevent event);
In this ontouch () we use gesturedetector to do the monitoring, with Gesturedetector to determine whether the user is in pull or pull.
More specifically, in the construction of Gesturedetector need to pass in a simpleongesturelistener, in fact, is overloaded Simpleongesturelistener onfling, In onfling to determine whether the Velocityy value is greater than 0 or less than 0, greater than 0 we think the user is in the dropdown, less than 0 we think the user is on the pull. Then, according to both cases, different ontop and Onbottom events are triggered respectively.


Code:


Test main Program (Mainactivity.java):

Package Zhangphil.listview;import Java.util.arraylist;import Android.app.activity;import android.os.Bundle;import Android.widget.arrayadapter;public class Mainactivity extends Activity {privatephillistview listview=null;private int DATA = 0; @Overrideprotected void onCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main); ListView = (Phillistview) Findviewbyid (R.id.phillistview); final ArrayList <String> items = new arraylist<string> ()///Android.r.layout.simple_list_item_1 loading data with the simplest Android system. Final arrayadapter<string> adapter = new Arrayadapter<string> (this,android. R.layout.simple_list_item_1, items); Listview.setadapter (adapter); Listview.setonpulltorefreshlistener (new Phillistview.onpulltorefreshlistener () {@Overridepublic void Onbottom () {Listview.onrefresh (true); Items.Add (" Pull up to tail append: "+ data++); adapter.notifydatasetchanged (); Listview.onrefresh (false);} @Overridepublic void OnTop () {Listview.onrefresh (true); iteMs.add (0, "drop to top add:" + data++); adapter.notifydatasetchanged (); Listview.onrefresh (false);}});}} 




The code design implements a dropdown/pull-up refresh list:

Package Zhangphil.listview;import Android.app.progressdialog;import Android.content.context;import Android.util.attributeset;import Android.view.gesturedetector;import Android.view.motionevent;import Android.view.view;import Android.widget.abslistview;import Android.widget.listview;public class PhilListView Extends ListView {private Context context;private int firstvisibleitem = 0;private int visibleitemcount = 0;private int to Talitemcount = 0;//A simple ball-shaped progress roller that indicates to the user that the private progressdialog is being loaded progressdialog = Null;private Onpulltorefreshlistener Monpulltorefreshlistener = null;public Phillistview (context context) {super (context); This.context = context;} Public Phillistview (context context, AttributeSet Attrs) {Super (context, attrs); this.context = context;} The callback interface, which is open here, allows the user to refresh with a pull-up bottoming or a drop-down peak. Public interface Onpulltorefreshlistener {//callback when the user's finger is pulled up on the screen to see the last element at the bottom of the ListView. public void Onbottom ();//callback when the user's finger is pulled down on the screen to see the first element of the top of the ListView. public void OnTop ();} public void SetonpulltorefreshlistEner (Onpulltorefreshlistener listener) {Monpulltorefreshlistener = Listener;this.setonscrolllistener (new Listview.onscrolllistener () {//assigns the latest value to Firstvisibleitem, VisibleItemCount, totalitemcount. @Overridepublic void  Onscroll (abslistview view, int arg0, int arg1, int arg2) {Firstvisibleitem = Arg0;visibleitemcount = Arg1;totalitemcount = Arg2;} @Overridepublic void onscrollstatechanged (abslistview view, int scrollstate) {}});// The mgesturedetector is used to monitor the user's swipe and slide events on the phone screen. The reason why use gesturedetector rather than rely entirely on listview.onscrolllistener, mainly because when the listview in 0 elements, or when the data element is not enough to scroll the display of multiple screens (in other words, the normal situation assumes that a screen can display 15, but the LIS Tview has only 3 elements, there will be plenty of empty space left below the ListView, and events in this space do not trigger listview.onscrolllistener. Final Gesturedetector mgesturedetector = new Gesturedetector (context,new Gesturedetector.simpleongesturelistener () {@ Overridepublic boolean onfling (motionevent E1, motionevent e2,float Velocityx, float velocityy) {//Velocityy is a vector, Velocityy indicates the vector distance the finger moves in the vertical direction (y-axis). When Velocityy >0, it indicates that the user's finger moves down on the screen. That is, the E2 event occurs below the point at which the E1 event occurred. We can therefore assume that usersDrop down: The user dropdown wants to see the data at the top. Then in this block of code, judging whether the first entry in the ListView is equal to 0,//equals 0 means that the ListView at this point is already sliding to the top of the Firstvisibleitem. The callback Monpulltorefreshlistener.ontop () is then started to trigger the ONTOP () event. if (Velocityy > 0) {if (Firstvisibleitem = = 0) {monpulltorefreshlistener.ontop ();}} The same as above, Velocityy < 0, at this time the E1 under the E2. Indicates that the user's finger moves upwards on the screen and wants to see the data at the bottom. Firstvisibleitem indicates the value of the first item on the screen currently visible,//VisibleItemCount is the number in the visible field of view. Totalitemcount is the ListView all item number//if Firstvisibleitem + visibleitemcount ==//Totalitemcount, then the ListView at this point is already bottoming out. if (Velocityy < 0) {int cnt = Firstvisibleitem + visibleitemcount;if (cnt = = Totalitemcount) {Monpulltorefreshlistener. Onbottom ();}} Return Super.onfling (E1, E2, Velocityx, Velocityy);}); This.setontouchlistener (New View.ontouchlistener () {//monitor touch events with Mgesturedetector. @Overridepublic boolean OnTouch (View V, motionevent event) {return mgesturedetector.ontouchevent (event);});}  /** * @param refreshing * * Controls the animation display during loading * ture: Display. * false: Close */public void Onrefresh (Boolean refreshing) {if (Refreshing) showprogress (); elsecloseprogress ();} Show ProgressDialog, indicating loading ... private void showprogress () {ProgressDialog = Progressdialog.show (Context, "Phillistview "," load, please wait ... ", true, True);} Off load shows private void closeprogress () {if (ProgressDialog! = null) Progressdialog.dismiss ();}}


Activity_main.xml required by Mainactivity.java:

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"    android:layout_width= "Match_ Parent "    android:layout_height=" match_parent "    android:orientation=" vertical ">    < Zhangphil.listview.PhilListView        android:id= "@+id/phillistview"        android:layout_width= "Match_parent"        android:layout_height= "Match_parent" >    </zhangphil.listview.phillistview></linearlayout >


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Android ListView Dropdown/Pull-up refresh: design principle and implementation

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.