最近的一个项目,由于改了一些需求,需要给列表加上上拉加载功能。之前列表用的是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
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
网友评论