Custom View -- pull and load by using the pull-down refresh component

Source: Internet
Author: User

Custom View -- pull and load by using the pull-down refresh component

Note: The demo in this article has been submitted to github. The complete address code is as follows. The demo project has been uploaded to GitHub,
Github address https://github.com/wsclwps123/UpLoadSwipeRefreshLayout
Thank you for your support!

In Android development, we often use the drop-down list refresh and pull-up functions.
Google provides a component in the support. v4 package that can be used for downloading and refreshing. This component is SwipeRefreshLayout.
Let's take a look at the usage of this component:
Add xml code to the layout File

        
  

Add the code to the MainActivity. java code:

/*** Add variable */private SwipeRefreshLayout swipeRefreshLayout; private ListView listView; private ArrayList
  
   
List = new ArrayList <> (); private ArrayAdapter
   
    
Adapter;
   
  

Initialize an instance in the onCreate method of Activity

/*** Instantiate the variable. The initList () method is omitted here. * This method adds N strings "item" */initList (); swipeRefreshLayout = (SwipeRefreshLayout) findViewById (R. id. swipe_refresh_layout); listView = (ListView) findViewById (R. id. list_view); adapter = new ArrayAdapter
  
   
(This, android. R. layout. simple_list_item_1, list); listView. setAdapter (adapter );
  

Next, add the OnRefreshListener listener to SwipeRefreshLayout.

swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {    @Override    public void onRefresh() {        Toast.makeText(MainActivity.this, "is refreshing!",          Toast.LENGTH_SHORT).show();    }});

Running Effect

However, in daily development, we not only need the pull-down and refresh functions, but should also have the functions of pulling and loading, but Google does not provide us with the method of pulling and loading. What should we do? We can customize a View and add the pull-up loading method by ourselves.

We mimic Swiperefreshlayout's use of the pull-down refresh method to design the load-up method. The Code that has been added to the pull-up is in the form

View. setOnLoadListener (new OnLoadListener () {@ Override public void onLoad () {// pull the loaded logic view here. setloading (false); // stop pulling and loading after logical execution }});

Therefore, we need to write an OnLoadListener interface before refresh the component from the rewrite drop-down list.

Public interface OnLoadListener {public void onLoad (); // method to be rewritten}

We write an UpLoadSwipeRefreshLayout class that inherits the SwipeRefershLayout class. When should we start pulling and loading? Of course, it is when the sub-ListView slides to the bottom, so we can start to load the top should meet the following conditions:
① Determine that the listview has slipped to the bottom
② Determine that the finger is sliding up
③ The current pull-up loading is not in progress

Writing Class
The Code is as follows:

Public class UpLoadSwipeRefreshLayout extends SwipeRefreshLayout {private ListView mListView; // sub-view private boolean isCanLoading = false; // whether the file can be loaded. private OnLoadListener mOnLoadListener; private View mFooterView by default; // private int firstY; private int lastY; private int mTouchSlop; // The shortest sliding distance from private int footerResource; // The resource ID public UpLoadSwipeRefreshLayout (Context context, AttributeSet attrs) {super (context, attrs); mTouchSlop = ViewConfiguration. get (getContext ()). getScaledTouchSlop (); // obtain the system's default shortest sliding distance }}

Because ListView is a sub-view of this component, we should check whether the Sub-view is a listview at the beginning.

Override onLayout () to obtain subclass

@ Override protected void onLayout (boolean changed, int left, int top, int right, int bottom) {super. onLayout (changed, left, top, right, bottom); if (mListView = null) {getListView (); // obtain the subview }}

Construct a getListView Method

Private void getListView () {int childs = getChildCount (); if (childs> 0) {View childView = getChildAt (0); // obtain the first subview if (childView instanceof ListView) {/*** if the subview type is ListView */mListView = (ListView) childView; // set the sliding listener mListView for the sublistview. setOnScrollListener (this );}}}

Rewrite event interception events to prevent conflict of sliding events

@ Override public boolean onInterceptTouchEvent (MotionEvent ev) {switch (ev. getAction () {case MotionEvent. ACTION_DOWN:/*** get the coordinates of the finger touch at the beginning of the touch event */firstY = (int) ev. getRawY (); break; case MotionEvent. ACTION_MOVE:/*** get the coordinates of the finger exit when the touch event ends */lastY = (int) ev. getRawY (); break; case MotionEvent. ACTION_UP: if (isCanLoad () {loadData () ;}break; default: break;} return super. onInterceptTouchEvent (ev );}

To get the slide of the sub-listview, we should let the component implement the OnScrollListener interface.
That is

Class UpLoadSwipeRefreshLayout extends SwipeRefreshLayout implements AbsListView. onScrollListener {@ Override public void onScrollStateChanged (AbsListView view, int scrollState) {}/ *** Override sliding time */@ Override public void onScroll (AbsListView view, int cursor, int visibleItemCount, int totalItemCount) {if (isCanLoad () {/*** if data can be loaded during the Sliding Process * execute the Data Loading Function */loadData ();}}}

Compile the isCanLoad () method. Here we use the three conditions we need to meet above.

private boolean isCanLoad() {    return isBottom() && isPushUp() && !isCanLoading;}

Write two methods in sequence

/*** Determine whether the listview has reached the bottom */private boolean isBottom () {if (mListView! = Null & mListView. getAdapter ()! = Null) {/*** the last item currently available is the last item of the listview * indicating that it slides to the bottom */return mListView. getLastVisiblePosition () = (mListView. getAdapter (). getCount ()-1);} return false ;}
/*** Determine whether pulling is in progress */private boolean isPushUp () {/*** the sliding distance is greater than the system's default sliding distance */return firstY-lastY> = mTouchSlop ;}

At this time, we also need to compile the loadData () method.

/*** Load data */private void loadData () {if (mOnLoadListener! = Null) {setLoading (true);/*** processing loading logic * The specific logic is completed in the callback */mOnLoadListener. onLoad ();}}

SetLoading ()

Public void setLoading (boolean isCanLoad) {this. isCanLoading = isCanLoad; if (isCanLoad = true) {/*** load, add the loading view at the bottom */mListView. addFooterView (mFooterView);} else {/*** is not loading. Remove the loading view at the bottom */mListView. removeFooterView (mFooterView); firstY = 0; lastY = 0 ;}}

By the way, no method has been added for setting up the listener to be loaded!
Compile the setOnUpLoadListener () method

public void setOnLoadListener(OnLoadListener onLoadListener) {    this.mOnLoadListener = onLoadListener;}

This class provides a variable that represents the resource id of the bottom view of listview.
You can use the setFooterResource method to add and instantiate the bottom view.
Write this method

Public void setFooterResource (int footerResource) {this. footerResource = footerResource;/*** instantiate Layout view */this. mFooterView = LayoutInflater. from (getContext ()). inflate (footerResource, null, false );}

At this time, we have compiled this class, and I will release the complete code at the end of the blog.
Let's take a look at the use of this Code.
Modify the layout file as follows:


          
   < listview>    
   
  

Add the resource id file of the last view, layout_up_load_view.xml


  
      
           
            
        
   
  

Modify MainActivity. java code

SwipeRefreshLayout. setFooterResource (R. layout. layout_up_load_view); // Add the view swipeRefreshLayout being loaded. setOnLoadListener (new OnLoadListener () {@ Override public void onLoad () {// actions on pulling and loading }});

Running Effect

The complete code is as follows. The demo project has been uploaded to GitHub.
Github address https://github.com/wsclwps123/UpLoadSwipeRefreshLayout

Package com. example. chenglei. myapplication; import android. content. context; import android. support. v4.widget. swipeRefreshLayout; import android. util. attributeSet; import android. view. layoutInflater; import android. view. motionEvent; import android. view. view; import android. view. viewConfiguration; import android. widget. absListView; import android. widget. listView;/*** Created by chenglei on 2016/4/20. * rewrite the drop-down brush New component: add the uploading function */public class UpLoadSwipeRefreshLayout extends SwipeRefreshLayout implements AbsListView. onScrollListener {private ListView mListView; // sub-view private boolean isCanLoading = false; // whether the Sub-View can be loaded; private OnLoadListener mOnLoadListener is disabled by default; private view mFooterView; // private int firstY; private int lastY; private int mTouchSlop; // The shortest sliding distance from private int footerResource; public UpL OadSwipeRefreshLayout (Context context, AttributeSet attrs) {super (context, attrs); mTouchSlop = ViewConfiguration. get (getContext ()). getScaledTouchSlop (); // obtain the system's default shortest sliding distance} @ Override protected void onLayout (boolean changed, int left, int top, int right, int bottom) {super. onLayout (changed, left, top, right, bottom); if (mListView = null) {getListView () ;}/ *** get subview */private void getList View () {int childs = getChildCount (); if (childs> 0) {View childView = getChildAt (0); // obtain the first child view if (childView instanceof ListView) {/*** if the subview type is ListView */mListView = (ListView) childView; // set the sliding listener mListView for the sublistview. setOnScrollListener (this) ;}}/ *** touch event interception */@ Override public boolean onInterceptTouchEvent (MotionEvent ev) {switch (ev. getAction () {case MotionEvent. ACTION_DOWN: /*** Get the coordinates of the finger touch at the beginning of the touch event */firstY = (int) ev. getRawY (); break; case MotionEvent. ACTION_MOVE:/*** get the coordinates of the finger exit when the touch event ends */lastY = (int) ev. getRawY (); break; case MotionEvent. ACTION_UP: if (isCanLoad () {loadData () ;}break; default: break;} return super. onInterceptTouchEvent (ev);}/*** determine whether loading is allowed */private boolean isCanLoad () {return isBottom () & isPushUp ()&&! IsCanLoading;}/*** determine whether the listview is at the bottom */private boolean isBottom () {if (mListView! = Null & mListView. getAdapter ()! = Null) {/*** the last item currently available is the last item of the listview * indicating that it slides to the bottom */return mListView. getLastVisiblePosition () = (mListView. getAdapter (). getCount ()-1);} return false;}/*** determine whether to pull up */private boolean isPushUp () {/*** the sliding distance is greater than the system's default sliding distance */return firstY-lastY> = mTouchSlop;} @ Override public void onScrollStateChanged (AbsListView view, int scrollState) {}@ Override public void onScroll (AbsListView vie W, int firstVisibleItem, int visibleItemCount, int totalItemCount) {if (isCanLoad ()) {/*** if data can be loaded during the Sliding Process *, execute the Data Loading Function */loadData ();}/*** load data */private void loadData () {if (mOnLoadListener! = Null) {setLoading (true);/*** process the loaded logic * The specific logic is completed in the callback */mOnLoadListener. onLoad () ;}/ *** set to load */public void setLoading (boolean isCanLoad) {this. isCanLoading = isCanLoad; if (isCanLoad = true) {/*** load, add the loading view at the bottom */mListView. addFooterView (mFooterView);} else {/*** is not loading. Remove the loading view at the bottom */mListView. removeFooterView (mFooterView); firstY = 0; lastY = 0 ;}}/*** set the listener to pull up */public void setOnLoadListener (OnLoadListener onLoadListener) {this. mOnLoadListener = onLoadListener;}/*** set the layout of the uploading. */public void setFooterResource (int footerResource) {this. footerResource = footerResource;/*** instantiate Layout view */this. mFooterView = LayoutInflater. from (getContext ()). inflate (footerResource, null, false );}}

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.