教你简单的实现ListView上拉加载

2018-01-23  本文已影响0人  androidboom

最近的一个项目,由于改了一些需求,需要给列表加上上拉加载功能。之前列表用的是ListView,改成RecyclerView改的地方还挺多,于是就想着自己写一个简单的支持加载更多的ListView。

上拉加载.gif

思路

————>ListView可以添加FootView,那么可以考虑用FootView作为加载布局。

————>那么什么情况下显示加载布局呢?当然是滑到底部就显示加载布局了。

————>但是怎么判断ListView是否滑到底部了呢?因为之前实现RecyclerView的上拉加载的时候,通过调用RecyclerView的addOnScrollListener()方法,判断是否加载到底部。所以可以看看ListView有没有类似的方法。通过查看ListView的API,果然,发现了setOnScrollListener()方法。

好了,这些条件都具备了,那么就可以开始实现了。

实现

一、首先,新建一个类继承自ListView,重写他的三个构造函数。

publicclassLoadMoreListViewextendsListViewimplementsAbsListView.OnScrollListener{publicLoadMoreListView(Context context){super(context);    }publicLoadMoreListView(Context context, AttributeSet attrs,intdefStyleAttr){super(context, attrs, defStyleAttr);    }publicLoadMoreListView(Context context, AttributeSet attrs){super(context, attrs);    }}

二、然后,在构造函数里对ListView进行初始化:添加FootView,设置setOnScrollListener()方法,实现OnScrollListener 接口,重写他的onScrollStateChanged()和onScroll()方法

publicclassLoadMoreListViewextendsListViewimplementsAbsListView.OnScrollListener{privateView mFootView;privateintmTotalItemCount;//item总数privateOnLoadMoreListener mLoadMoreListener;privatebooleanmIsLoading=false;//是否正在加载publicLoadMoreListView(Context context){super(context);        init(context);    }publicLoadMoreListView(Context context, AttributeSet attrs,intdefStyleAttr){super(context, attrs, defStyleAttr);        init(context);    }publicLoadMoreListView(Context context, AttributeSet attrs){super(context, attrs);        init(context);    }privatevoidinit(Context context){        mFootView= LayoutInflater.from(context).inflate(R.layout.foot_view,null);        setOnScrollListener(this);    }}

下面是foot_view布局:

三、再然后,重写onScrollStateChanged()和onScroll()方法,判断是否到达底部

@OverridepublicvoidonScrollStateChanged(AbsListView listView,intscrollState){// 滑到底部后,判断listview已经停止滚动并且最后可视的条目等于adapter的条目intlastVisibleIndex=listView.getLastVisiblePosition();if(!mIsLoading&&scrollState == OnScrollListener.SCROLL_STATE_IDLE//停止滚动&& lastVisibleIndex ==mTotalItemCount-1) {//滑动到最后一项mIsLoading=true;            addFooterView(mFootView);if(mLoadMoreListener!=null) {                mLoadMoreListener.onloadMore();            }        }    }@OverridepublicvoidonScroll(AbsListView absListView,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount){        mTotalItemCount=totalItemCount;    }

其中scrollState == OnScrollListener.SCROLL_STATE_IDLE表示,listView停止滑动。

lastVisibleIndex ==mTotalItemCount-1表示滑动到最后一行了。

四、然后,写一个方法,设置加载完毕,控制加载布局消失。

publicvoidsetLoadCompleted(){        mIsLoading=false;      removeFooterView(mFootView);    }

五、最后新建一个接口OnLoadMoreListener以及一个setOnLoadMoreListener()方法,供外部调用加载更多的事件

publicvoidsetONLoadMoreListener(OnLoadMoreListener listener){        mLoadMoreListener=listener;    }publicinterfaceOnLoadMoreListener{voidonloadMore();    }

如何使用

使用方法和ListView一样。

首先布局文件:

然后在Activity中:

mListView.setOnLoadMoreListener(newLoadMoreListView.OnLoadMoreListener() {@OverridepublicvoidonloadMore(){                loadMore();            }        });

loadmore()方法中,处理加载更多数据的逻辑:

privatevoidloadMore(){newThread(){@Overridepublicvoidrun(){super.run();try{                    Thread.sleep(2000);                }catch(InterruptedException e) {                    e.printStackTrace();                }                mData.add("atate");                mData.add("546646");                mData.add("546646");                runOnUiThread(newRunnable() {@Overridepublicvoidrun(){                        adapter.notifyDataSetChanged();                        mListView.setLoadCompleted();                    }                });            }        }.start();    }

注意架加载完成之后,要调用setLoadCompleted()方法,控制加载布局消失

完整代码

packageorg.raphets.demoloadmorelistview;importandroid.content.Context;importandroid.util.AttributeSet;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.widget.AbsListView;importandroid.widget.ListView;/**

* Created by RaphetS on 2016/10/14.

*/publicclassLoadMoreListViewextendsListViewimplementsAbsListView.OnScrollListener{privateContext mContext;privateView mFootView;privateintmTotalItemCount;privateOnLoadMoreListener mLoadMoreListener;privatebooleanmIsLoading=false;publicLoadMoreListView(Context context){super(context);        init(context);    }publicLoadMoreListView(Context context, AttributeSet attrs,intdefStyleAttr){super(context, attrs, defStyleAttr);        init(context);    }publicLoadMoreListView(Context context, AttributeSet attrs){super(context, attrs);        init(context);    }privatevoidinit(Context context){this.mContext=context;        mFootView= LayoutInflater.from(context).inflate(R.layout.foot_view,null);        setOnScrollListener(this);    }@OverridepublicvoidonScrollStateChanged(AbsListView listView,intscrollState){// 滑到底部后自动加载,判断listview已经停止滚动并且最后可视的条目等于adapter的条目intlastVisibleIndex=listView.getLastVisiblePosition();if(!mIsLoading&&scrollState == OnScrollListener.SCROLL_STATE_IDLE                && lastVisibleIndex ==mTotalItemCount-1) {            mIsLoading=true;            addFooterView(mFootView);if(mLoadMoreListener!=null) {                mLoadMoreListener.onloadMore();            }        }    }@OverridepublicvoidonScroll(AbsListView absListView,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount){        mTotalItemCount=totalItemCount;    }publicvoidsetOnLoadMoreListener(OnLoadMoreListener listener){        mLoadMoreListener=listener;    }publicinterfaceOnLoadMoreListener{voidonloadMore();    }publicvoidsetLoadCompleted(){        mIsLoading=false;      removeFooterView(mFootView);    }}

footView布局:

Demo地址

https://github.com/RaphetS/LoadMoreListView

最后

以上代码若是有什么问题,希望大家多多指教。希望能和大家互相学习,共同进步。谢谢。

作者:RaphetS

链接:https://www.jianshu.com/p/c1c4512ef7f7

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

上一篇下一篇

猜你喜欢

热点阅读