Android RecyclerView Swipe Refresh Tutorial

In previous tutorial, I have implement a simple recyclerview tutorial to let you understand how its work. The recyclerview only display the static content is not a good practice. We should implement the refresh feature swipe up or down in the recyclerview to refresh the new content from the database or only visible 10 item per load. The swipe down refresh is very useful when come to you dont want to display all item at a time because it will cause the android app lag or some serious problem occur in the user device. So that you want to load and refresh only 10 items per refresh. This tutorial, I will provide the android recyclerview swipe refresh feature in this android project. So you will get use on it.

Creating a new Project

1. Open Android Studio IDE in your computer.
2. Create a new project and Edit the Application name to “SwipeRefreshRecyclerViewExample”.
(Optional) You can edit the company domain or select the suitable location for current project tutorial. Then click next button to proceed.
3. Select Minimum SDK (API 15:Android 4.0.3 (IceCreamSandwich). I choose the API 15 because many android devices currently are support more than API 15. Click Next button.
4. Choose “Empty Project” and Click Next button
5. Lastly, press finish button.

Add the new dependency

Include the recyclerview library in your androidmanifest file so you can use the recyclerview in your project later. After that click synchronise.

compile 'com.android.support:recyclerview-v7:25.0.0'

Create a item view layout

Right click the res>layout folder and create a new xml layout “item_view” for the each item view.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tvItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
       />

</LinearLayout>

Create a progress view layout

Same as previous, create a layout but name it to “item_progress” after that follow the source code in the bottom.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ProgressBar
        android:id="@+id/pBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="true"/>

</LinearLayout>

Create a Modal class

Besides, add a new modal class “Item” and follow the sample source code below, I will add one string name item.

public class Item  {

    private String item;

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }


    public Item(String item) {
        this.item=item;
    }

}

Create a new Adapter for Item

Create a new Adapter class “ItemAdapter”, if the item position is null then it will be show the progress bar.

public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>  {
    private final int VIEW_ITEM = 1;
    private final int VIEW_PROG = 0;

    private ArrayList<Item> itemList;

    private OnLoadMoreListener onLoadMoreListener;
    private LinearLayoutManager mLinearLayoutManager;

    private boolean isMoreLoading = false;
    private int visibleThreshold = 1;
    int firstVisibleItem, visibleItemCount, totalItemCount;

    public interface OnLoadMoreListener{
        void onLoadMore();
    }

    public ItemAdapter(OnLoadMoreListener onLoadMoreListener) {
        this.onLoadMoreListener=onLoadMoreListener;
        itemList =new ArrayList<>();
    }

    public void setLinearLayoutManager(LinearLayoutManager linearLayoutManager){
        this.mLinearLayoutManager=linearLayoutManager;
    }

    public void setRecyclerView(RecyclerView mView){
        mView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                visibleItemCount = recyclerView.getChildCount();
                totalItemCount = mLinearLayoutManager.getItemCount();
                firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
                if (!isMoreLoading && (totalItemCount - visibleItemCount)<= (firstVisibleItem + visibleThreshold)) {
                    if (onLoadMoreListener != null) {
                        onLoadMoreListener.onLoadMore();
                    }
                    isMoreLoading = true;
                }
            }
        });
    }

    @Override
    public int getItemViewType(int position) {
        return itemList.get(position) != null ? VIEW_ITEM : VIEW_PROG;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
        if (viewType == VIEW_ITEM) {
            return new ItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false));
        } else {
            return new ProgressViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_progress, parent, false));
        }

    }

    public void addAll(List<Item> lst){
        itemList.clear();
        itemList.addAll(lst);
        notifyDataSetChanged();
    }

    public void addItemMore(List<Item> lst){
        itemList.addAll(lst);
        notifyItemRangeChanged(0,itemList.size());
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof ItemViewHolder) {
            Item singleItem = (Item) itemList.get(position);
            ((ItemViewHolder) holder).tvItem.setText(singleItem.getItem());
        }
    }

    public void setMoreLoading(boolean isMoreLoading) {
        this.isMoreLoading=isMoreLoading;
    }

    @Override
    public int getItemCount() {
        return itemList.size();
    }

    public void setProgressMore(final boolean isProgress) {
        if (isProgress) {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    itemList.add(null);
                    notifyItemInserted(itemList.size() - 1);
                }
            });
        } else {
            itemList.remove(itemList.size() - 1);
            notifyItemRemoved(itemList.size());
        }
    }

    static class ItemViewHolder extends RecyclerView.ViewHolder {
        public TextView tvItem;

        public ItemViewHolder(View v) {
            super(v);
            tvItem = (TextView) v.findViewById(R.id.tvItem);
        }
    }

    static class ProgressViewHolder extends RecyclerView.ViewHolder {
        public ProgressBar pBar;
        public ProgressViewHolder(View v) {
            super(v);
            pBar = (ProgressBar) v.findViewById(R.id.pBar);
        }
    }
}

Edit activity_main.xml layout

Go to activity_main.xml file and add the swiperefreshlayout such as the source code below.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rvList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical"/>
    </android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>

Edit MainActivity.java class

Modify your mainactivity class and this class will handler the swipe feature in the recyclerview.

public class MainActivity extends AppCompatActivity implements ItemAdapter.OnLoadMoreListener
        ,SwipeRefreshLayout.OnRefreshListener{

    private ItemAdapter mAdapter;
    private ArrayList<Item> itemList;
    private SwipeRefreshLayout swipeRefresh;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        itemList = new ArrayList<Item>();
        swipeRefresh=(SwipeRefreshLayout)findViewById(R.id.swipeRefresh);
        RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.rvList);
        LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mAdapter = new ItemAdapter(this);
        mAdapter.setLinearLayoutManager(mLayoutManager);
        mAdapter.setRecyclerView(mRecyclerView);
        mRecyclerView.setAdapter(mAdapter);
        swipeRefresh.setOnRefreshListener(this);


    }

    @Override
    protected void onStart() {
        super.onStart();
        loadData();
    }

    @Override
    public void onRefresh() {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                swipeRefresh.setRefreshing(false);
                loadData();

            }
        },2000);
    }

    @Override
    public void onLoadMore() {

        mAdapter.setProgressMore(true);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                itemList.clear();
                mAdapter.setProgressMore(false);
                int start = mAdapter.getItemCount();
                int end = start + 15;
                for (int i = start + 1; i <= end; i++) {
                    itemList.add(new Item("Item " + i));
                }
                mAdapter.addItemMore(itemList);
                mAdapter.setMoreLoading(false);
            }
        },2000);
    }

    private void loadData() {
        itemList.clear();
        for (int i = 1; i <= 20; i++) {
            itemList.add(new Item("Item " + i));
        }
        mAdapter.addAll(itemList);
    }

}

Run you Project

At last, you can try to run this project and test the refresh feature that just implement.

(Android RecyclerView Swipe Refresh)

Source Code

(Visited 2,069 times, 1 visits today)
Advertisements

Yong Loon Ng

Ng Yong Loon, better known as Kristofer is a software engineer and computer scientist who doubles up as an entrepreneur.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *