PullToRefresh实现下拉刷新和上拉加载更多的ListView
来源:互联网 发布:自考,成考,远程网络 编辑:程序博客网 时间:2024/06/03 14:30
使用PullToRefresh实现下拉刷新和上拉加载更多的ListView效果如下:
PullToRefresh是非常好用的第三方下拉刷新库,它支持:
1.ListView
2.ExpandableListView
3.GridView
4.WebView
等多种常用的需要刷新的View控件,基本上能够满足我们的开发需要。
下面结合一个小Demo介绍一下使用PullToRefresh实现下拉刷新和上拉加载更多的ListView的方法:
(一) 先到GitHub上下载PullToRefresh的类库,下载地址是:
https://github.com/chrisbanes/Android-PullToRefresh
(二) 解压缩后,导入library到自己的工程目录下,然后让使用此功能的Module与library建立依赖。
library给我们提供了常用控件的实现代码,我们可以参照这些代码来自己开发:
(三) 如何理解下拉刷新和上拉加载更多?
我感觉这段说的很到位:
下拉刷新是重新加载列表,重新请求数据;而上拉加载更多,是在已有列表的基础上,根据当前客户端显示的最后一个item的ID值,找到后续的若干个Item数据,返回给客户端,添加到当前列表的末尾显示的;就发送请求和返回数据的技术而言,没有区别,区别在SQL语句;还有对于Listview是重置列表数据,还是添加数据到列表末尾的问题。
(四)setMode 设置模式:
- Mode.BOTH:同时支持上拉下拉
- Mode.PULL_FROM_START:只支持下拉Pulling Down
- Mode.PULL_FROM_END:只支持上拉Pulling Up
- DISABLED 不支持刷新功能
也可以用 ptr:ptrMode="both"
可选值为:disabled(禁用下拉刷新),pullFromStart(仅支持下拉刷新),pullFromEnd(仅支持上拉刷新),both(二者都支持),manualOnly(只允许手动触发)
如果Mode设置成Mode.BOTH,需要设置刷新Listener为OnRefreshListener2,并实现onPullDownToRefresh()、onPullUpToRefresh()两个方法。
如果Mode设置成Mode.PULL_FROM_START或Mode.PULL_FROM_END,需要设置刷新Listener为OnRefreshListener,同时实现onRefresh()方法。
当然也可以设置为OnRefreshListener2,但是Mode.PULL_FROM_START的时候只调用onPullDownToRefresh()方法,Mode.PULL_FROM的时候只调用onPullUpToRefresh()方法.
如果想上拉、下拉刷新的时候 做一样的操作,那就用OnRefreshListener,上拉下拉的时候都调用
如果想上拉、下拉做不一样的的操作,那就在setOnRefreshListener时 用new OnRefreshListener2<ListView>
(五) 实现上面效果的代码:
①MainActivity代码:
<span style="font-size:18px;"><span style="font-size:18px;">/** * 下拉刷新,上拉加载更多 * 上拉加载更多,数据量大需要分页,减少内消耗。避免用户快速向下滑动,减少流量 * 下拉刷新,用户习惯 * 使用第三方 Xlistview pulltorefreshlistview * 官方(下拉刷新,但是没有上拉加载更多) * pulltorefreshview其实都是一个自定义的布局,里面包裹着Listview或者其他的控件 */public class MainActivity extends AppCompatActivity { protected PullToRefreshListView mPullToRefreshList; private MyAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.activity_main); initView(); //第一次加载数据,默认我下拉刷新 initData(false); /** * 设置模式 * DISABLED 不启用刷新功能 * PULL_FROM_START 仅支持下拉 * PULL_FROM_END 仅支持上拉 * BOTH 支持上拉和下拉 * MANUAL_REFRESH_ONLY 不支持手势刷新,但是支持使用点击或者其他动作通过代码手动调用刷新 * */ mPullToRefreshList.setMode(PullToRefreshBase.Mode.BOTH); //如果mode为both时(即有两种状态),使用这个监听 mPullToRefreshList.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() { //开始下拉 我们需要在用户下拉的时候重新做http请求 @Override public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) { initData(false); } @Override public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) { initData(true); } }); mAdapter = new MyAdapter(); mPullToRefreshList.setAdapter(mAdapter); //如果需要自定义头标题,先拿到原生控件,在原生控件的基础上添加头标题 //ListView refreshableView = mPullToRefreshList.getRefreshableView(); //refreshableView.addHeaderView(null); //获取一个头部和尾部的布局 ILoadingLayout loadingLayoutProxy = mPullToRefreshList.getLoadingLayoutProxy(); loadingLayoutProxy.setRefreshingLabel("正在刷新..."); // 刷新时 loadingLayoutProxy.setPullLabel("下拉刷新"); // 刚下拉时,显示的提示 loadingLayoutProxy.setLoadingDrawable(getResources().getDrawable(R.mipmap.ic_launcher)); loadingLayoutProxy.setLastUpdatedLabel("刚刚"); //一般是上次刷新的时间 loadingLayoutProxy.setReleaseLabel("松手开始刷新"); } private void initView() { mPullToRefreshList = (PullToRefreshListView) findViewById(R.id.pullToRefresh); } //要获取实体类中的数据 private List<ListData.ResultEntity> mResult = new ArrayList<>(); /** * 获取数据,参数为判断是上拉加载更多,还是下拉刷新 */ private void initData(final boolean isUP) { //使用xutils获取网络数据 HttpUtils httpUtils = new HttpUtils(); String url = "http://api.shigeten.net/api/Critic/GetCriticList"; httpUtils.send(HttpRequest.HttpMethod.GET, url, new RequestCallBack<String>() { @Override public void onSuccess(ResponseInfo<String> responseInfo) { //使用Gson解析之前需导包 Gson gson = new Gson(); ListData listData = gson.fromJson(responseInfo.result, ListData.class); List<ListData.ResultEntity> result = listData.getResult(); if (isUP) { //上拉加载更多 mResult.addAll(result); mAdapter.setResults(mResult); mAdapter.notifyDataSetChanged(); } else { //下拉刷新 mAdapter.setResults(result); mAdapter.notifyDataSetChanged(); } //刷新完成提供给我们手动调用 mPullToRefreshList.onRefreshComplete(); Toast.makeText(MainActivity.this, "数据请求成功", Toast.LENGTH_SHORT).show(); } @Override public void onFailure(HttpException error, String msg) { Log.e("onFailure", error.getMessage()); } }); }}</span></span>
注:上面的代码用到了第三方框架xUtils和和Gson,需要提前把这两个包导入。
②对应的自定义适配器代码:
<span style="font-size:18px;"><span style="font-size:18px;">public class MyAdapter extends BaseAdapter { List<ListData.ResultEntity> results; public void setResults(List<ListData.ResultEntity> results) { this.results = results; } @Override public int getCount() { return results == null ? 0 : results.size(); } @Override public Object getItem(int position) { return results.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null){ convertView = View.inflate(parent.getContext(),R.layout.item,null); holder = new ViewHolder(); holder.iv = (ImageView) convertView.findViewById(R.id.img); holder.tv = (TextView) convertView.findViewById(R.id.text); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } ListData.ResultEntity resultEntity = results.get(position); holder.tv.setText(resultEntity.getTitle()); BitmapUtils bitmapUtils = new BitmapUtils(parent.getContext()); bitmapUtils.display(holder.iv, "http://api.shigeten.net/" + resultEntity.getImage()); return convertView; } class ViewHolder{ private TextView tv; private ImageView iv; }}</span></span>
<span style="font-size:18px;"><span style="font-size:18px;">public class ListData { /* * status : 0 * errMsg : null */ private int status; private Object errMsg; /** * id : 100045 * type : 1 * publishtime : 636107040000000000 * title : 《瑞士军刀男》人生已经如此艰难,就不要拆穿 * summary : 看似荒诞,实则厚重。生与死的距离其实真的不远,自我认知与自我救赎也只是一线之隔。不知道有没有人和我一样,看到最后尸体踏浪而去的时候内心澎湃不已。 * image : images/B0181F9BC6EFC33D0396A16556952710.jpg */ private List<ResultEntity> result; public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public Object getErrMsg() { return errMsg; } public void setErrMsg(Object errMsg) { this.errMsg = errMsg; } public List<ResultEntity> getResult() { return result; } public void setResult(List<ResultEntity> result) { this.result = result; } public static class ResultEntity { private int id; private int type; private long publishtime; private String title; private String summary; private String image; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getType() { return type; } public void setType(int type) { this.type = type; } public long getPublishtime() { return publishtime; } public void setPublishtime(long publishtime) { this.publishtime = publishtime; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } }}</span></span>
④主布局代码activity_main.xml:
<span style="font-size:18px;"><span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.pulltorefreshlistview.MainActivity"> <com.handmark.pulltorefresh.library.PullToRefreshListView android:id="@+id/pullToRefresh" android:layout_width="match_parent" android:layout_height="match_parent"/></RelativeLayout></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><?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"> <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content"/></LinearLayout></span></span>
- PullToRefresh实现下拉刷新和上拉加载更多的ListView
- ListView下拉刷新和上拉加载更多的实现
- PullToRefresh实现简单的下拉刷新和上拉加载更多
- 下拉刷新,上拉加载更多 PullToRefresh
- Android ListView下拉刷新上拉加载更多的实现
- listview下拉刷新,上拉加载更多的实现方法
- Android实现ListView的下拉刷新、上拉加载更多
- listview的下拉刷新和上拉加载更多
- listview的上拉加载更多和下拉刷新
- 自定义ListView的下拉刷新和上拉加载更多
- PullToRefresh上拉刷新下拉加载更多的使用
- 【Android开发笔记】pulltorefresh实现下拉刷新和上拉加载更多
- android 使用PullToRefresh实现下拉刷新和上拉加载更多
- Pulltorefresh实现ListView下拉刷新,上拉加载
- PullToRefresh上拉加载下拉刷新GridView和ListView
- ListView实现下拉刷新(第一次打开listView的界面进行自动刷新)和上拉加载更多
- 采用github上的开源项目Android-PullToRefresh实现ListView的下拉刷新和上拉加载
- ListView下拉刷新上拉加载更多实现
- C语言#define STR3 STR STR1 STR2的理解
- PAT 乙级 1006 换个格式输出整数
- 动态规划的方法求解斐波那契数列
- eclipse的new server里tomcat7.0根本点不动解决方案
- js中几种实用的跨域方法原理详解
- PullToRefresh实现下拉刷新和上拉加载更多的ListView
- Activity的加载模式
- 手把手教你修改iOS版QQ的运动步数
- 安卓日记——一个从相册或者相机获取照片的工具类
- slab分配器--Linux内存管理(二十二)
- java编程思想读书笔记 第十一章 持有对象(下)
- android studio初学者了解
- JSP的四大域对象
- 信号处理