Premise:

Now Android apps on the market as long as they involve network interaction, almost all have the pull-up refresh function. Whether it is the news of the kind of simple book digging gold, or live fish fire cat. There are numerous frames on the Internet. SwipeToLoadLayout, which I used earlier, is a great drop-down refresh framework. However, Google released SwipeRefreshLayout after 5.0. Personally, I like the Material Design style. Google, after all, was born with a halo. Ha ha, no idle chatter, let’s get down to business.

1. SwipeRefreshLayout usage:


image.png


You can see from the source code, its own inheritance and ViewGroup. So just use it like a normal ViewGroup.

/ / XML code < android. Support. The v4. Widget. SwipeRefreshLayout android: id = "@ + id/SwipeRefreshLayout" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="wrap_content"/> </android.support.v4.widget.SwipeRefreshLayout>Copy the code

Here are a few SwipeRefreshLayout code basic usage:

/ / the drop-down refresh circle whether display refreshLayout setRefreshing (false); The color of the circle when / / set the drop-down (made of a variety of color Mosaic) refreshLayout. SetColorSchemeResources (android. R.c olor. Holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light); / / set the background color of the circle when the drop-down (set to white) refreshLayout. SetProgressBackgroundColorSchemeResource (android. R.c olor. White); / / set the drop-down refresh operation refreshLayout. SetOnRefreshListener (new SwipeRefreshLayout. OnRefreshListener () {@ Override public void OnRefresh () {// Specific operation ·····}});Copy the code

This is a simple drop-down refresh, simple. Ha ha.

2. Pull-up loading:

The important thing is that Google only provides pull-down refresh, but it doesn’t provide pull-up loading like other pull-down refresh frameworks do. What can we do about it? Don’t worry. SwipeRefreshLayout SwipeRefreshLayout SwipeRefreshLayout SwipeRefreshLayout SwipeRefreshLayout SwipeRefreshLayout SwipeRefreshLayout Unlike the traditional pull-down refresh framework, there will be a significant pull-up action. It slides to a certain position and automatically loads. This results in a better user experience and saves time waiting for pull-up loads.

Code:
private class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private final static int TYPE_CONTENT=0; Private final static int TYPE_FOOTER=1; private final static int TYPE_FOOTER=1; @override public int getItemViewType(int position) {if (position== listdata.size ()){return TYPE_FOOTER; } return TYPE_CONTENT; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType==TYPE_FOOTER){ View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_main_foot, parent, false); return new FootViewHolder(view); } else { View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_main_item, parent, false); MyViewHolder myViewHolder = new MyViewHolder(view); return myViewHolder; } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { if (getItemViewType(position)==TYPE_FOOTER){ } else{ MyViewHolder viewHolder= (MyViewHolder) holder; ViewHolder. TextView. SetText (" first "+ position +" line "); } } @Override public int getItemCount() { return listData.size()+1; } } private class MyViewHolder extends RecyclerView.ViewHolder { private TextView textView; public MyViewHolder(View itemView) { super(itemView); textView = itemView.findViewById(R.id.textItem); } } private class FootViewHolder extends RecyclerView.ViewHolder{ private ContentLoadingProgressBar progressBar; public FootViewHolder(View itemView) { super(itemView); progressBar=itemView.findViewById(R.id.pb_progress); }}Copy the code
Analysis:

The display is divided into two parts, one is the normal display and the other is the bottom-sliding ProgressBar. Add a progressBar to RecyclerView as a footer. It doesn’t have to be a Progressbar as a footer, but you can define what the progressbar View is.

Because you manually added a Footer to RecyclerView, the number of items displayed in RecyclerView was +1.

@Override public int getItemCount() { return listData.size()+1; //listData is the data source}Copy the code

Add a footer at the bottom when recyclerView slides to the bottom. So you set up two viewHolder, one for the normal content and one for the custom view that is displayed when you slide to the bottom

private final static int TYPE_CONTENT=0; Private final static int TYPE_FOOTER=1; private final static int TYPE_FOOTER=1; Public int getItemViewType(int position) {if (position== listdata.size ()){return TYPE_FOOTER; // The ViewType returned when the slider reaches the bottom is TYPE_CONTENT. } return TYPE_CONTENT; }Copy the code

Recyclerview onCreateViewHolder: According to the viewType to judge which viewHolder recyclerView should bind. Here we define two viewHolder, a MyViewHolder(viewTpye==TYPE_CONTENT) for normal loading of content, and a FootViewHolder(viewTpye==TYPE_FOOTER) for sliding to the low end.

@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType==TYPE_FOOTER){ View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_main_foot, parent, false); return new FootViewHolder(view); } else { View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_main_item, parent, false); MyViewHolder myViewHolder = new MyViewHolder(view); return myViewHolder; }}Copy the code
Customize the code for ViewHolder
private class MyViewHolder extends RecyclerView.ViewHolder { private TextView textView; public MyViewHolder(View itemView) { super(itemView); textView = itemView.findViewById(R.id.textItem); } } private class FootViewHolder extends RecyclerView.ViewHolder{ private ContentLoadingProgressBar progressBar; public FootViewHolder(View itemView) { super(itemView); progressBar=itemView.findViewById(R.id.pb_progress); }}Copy the code
activity_main_item.xml
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardElevation="2dp"
    android:layout_margin="5dp"
    tools:context="app.com.swiperefreshlayout.activity.MainActivity">
    <TextView
        android:id="@+id/textItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="45dp"
        android:text=""
        android:gravity="center"/>
</android.support.v7.widget.CardView>
Copy the code
activity_main_foot.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v4.widget.ContentLoadingProgressBar android:id="@+id/pb_progress"  style="?android:attr/progressBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> </LinearLayout>Copy the code
The rest is bound to onBindViewHolder
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, Final int position) {if (getItemViewType(position)==TYPE_FOOTER){else{MyViewHolder viewHolder= (MyViewHolder) holder; ViewHolder. TextView. SetText (" first "+ position +" line "); }}Copy the code

Pull-up load Listener

SwipeRefreshLayout’s OnRefreshListener () interface for drop-down refresh. And recyclerView does not have a pull-up loading interface, here we can define a.

RecyclerView. OnScrollListener () has two overriding methods, one is onScrolled is another onScrollStateChanged let’s analyze this two methods.

OnScrollStateChanged:


onScrollStateChanged.png


NewState shown in the source code is the status value of update slide no. There are three values, SCROLL_STATE_DRAGGING: Drag (a state value returned by Recyclerview sliding) SCROLL_STATE_SETTLING: Stop (Recyclerview stopped state value returned when the finger has left the screen but Recyclerview may still be sliding due to inertia) SCROLL_STATE_IDLE: Idle (state value returned when Recyclerview is idle, Recyclerview stops completely)

OnScrolled:


onScrolled.png


See the source code that this method is called when recyclerView sliding method. Dx is the distance when you slide horizontally, dy is the distance when you slide vertically.

Rewrite OnScrollListener

You know what these two methods and parameters do. We’re going to rewrite the sliding interface. As shown below:

/** * @author JTL. * @ Date 2017/12/1. * @ Description: Load more Listener * / public abstract class onLoadMoreListener extends RecyclerView. OnScrollListener {private int countItem; private int lastItem; private boolean isScolled = false; . / / whether can slide private RecyclerView LayoutManager LayoutManager; /** * loading callback method * @param countItem total number * @param lastItem last displayed position */ protected abstract void onLoading(int countItem, int lastItem); @Override public void onScrollStateChanged(RecyclerView recyclerView, If (newState==SCROLL_STATE_IDLE){log. d("test","SCROLL_STATE_IDLE, idle "); } else if (newState==SCROLL_STATE_DRAGGING){log.d ("test","SCROLL_STATE_DRAGGING, dragging "); } else if (newState== scroll_state_explained){log.d ("test"," scroll_state_explained, fixed "); } else{log.d ("test"," other "); } * / / / drag or inertia sliding isScolled is set to true if (newState because = = SCROLL_STATE_DRAGGING | | newState because = = SCROLL_STATE_SETTLING) {isScolled = true; } else { isScolled = false; } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) { layoutManager = recyclerView.getLayoutManager(); countItem = layoutManager.getItemCount(); lastItem = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition(); } if (isScolled && countItem ! = lastItem && lastItem == countItem - 1) { onLoading(countItem, lastItem); }}}Copy the code
Call onLoadMoreListener:

After writing this class, we can call it directly from our Activity.

recyclerView.addOnScrollListener(new onLoadMoreListener() { @Override protected void onLoading(int countItem,int lastItem) { handler.postDelayed(new Runnable() { @Override public void run() { getData("loadMore"); }}, 1000); }});Copy the code

Here are two giFs to see the effect




refresh.gif

loadmore.gif

A simple pull-down load and pull-up auto-refresh will do. If you have any questions, please discuss them together. Like the point of a like is also a little power to me. Thanks, ha ha!

Demo address: github.com/13046434521… .