RecycleView配合SwipeRefreshLayout实现轻量级上拉刷新下拉加载,外加牛X的Adapter
2016-11-10 12:12
519 查看
看过我这边文章的RecyclerView.Adapter的优化与封装的真的想说声抱歉,其实不需要继承BaseBean,只需要继承Object就可以了,而且更灵活了,当时不知道咋了,脑袋抽风了,多次了这一举。
好了,今天来一个更牛逼的神器RefreshLayout
效果图:
实现了上拉刷新和下拉加载功能
封装好的BaseAdapter和BaseViewHolder,将adapter交给Activity来管理
实现了单击事件和长单击事件
类结构图:
这个demo我把之前的BaseAdapter和BaseViewHolder的封装都重新整理了一边,然后把BaseAdapter抽象给Activity来管理,因为我发现我在之前的博文中封装的BaseAdapter,然后让其他的adapter去继承他去操作,这个adapter根本就不需要多少的操作,而且有点冗余,好多的adapter,烦,所以我打算把BaseAdapter的管理交给Activity去实现,这样,整个项目只需要一个BaseAdapter和BaseViewHolder去操作就行了,真的是万能的适配器啊,项目瞬间清爽了起来。好了,今天先来说说实现思路:
因为下拉加载SwipeRefreshLayout大家都知道的,官方的,没什么好讲,但是在处理上拉加载的时候这个下拉在后面还需要去处理,所以,先来讲上拉加载更多。
上拉加载更多需要哪些实现呢?
计算所有的RecycleView的item数量(即layoutManager.getItemCount())
获取当前页面底部可见的item的position位置(即LayoutManager.findLastVisibleItemPosition())
判断这个可见的position是否大于等于RecycleView的item数量减1(因为position是从0开始的)
我们还需要一个getChildCount辅助方法,获取当前整个屏幕显示的item数量,目的是判断有无item,来处理item不满一屏幕的时候处理。
当数据不满一屏幕的时候,SwipeRefreshLayout下拉的时候会触发我在onScrollStateChanged里面做的判断,然而这个判断是满足上拉加载更多的,会出现上拉加载刷新和下拉加载更多同时调用,然后看见数据突然的闪一下恢复到原来的数据,为了解决数据不满一屏的操作的bug,我在onTouch里面做了一个手势的处理,如果是向下拉,则给上拉加载更多的判断设置个flag为false,不让他去处理,亲测完美解决。
上代码,来看看RefreshRecycleView.java
代码特别简单,
在滑动事件里面去判断当前上否是滑动状态,然后判断上拉加载更多是否可用,当前的回调是否已经注册。
获取RecycleView在不同LayoutManager的时候返回的底部可见的position的位置
layoutManager.getChildCount()是获取当前可见界面的item数量
lastVisibleItemPosition获取item可见的最底部的position位置
layoutManager.getItemCount()是获取整个RecycleView的item的总数
然后对当前进行判断,
falg是处理onTouch返回的数据不满一屏幕的判断,
其他的判断大家看看就懂的,不难
然后显示dialog,回调load接口,给别人去处理
好了,这时候来看看包装RefreshRecycleView的类RefreshLayout.java了
看看xml就懂了
RefreshLayout只是对RecycleView的一种包装,专门处理上拉刷新和下拉加载更多,将所有事件的处理通过这个辅助类传递给Activity的调用者,外者只需要调用,不需要管理实现原理,简洁了代码。来看看代码
初始化xml,将view界面inflater到RefreshLayout
给下拉刷新和上拉加载进行注册
然后设置下拉刷新完成和上拉加载完成,这个大家应该都懂的,全是包装
然后注册个接口,将下拉和上拉的触发交个回调者来处理
这时候包装都结束了,最后来看看Activity来调用看看
下拉和上拉就这么搞定了,哈哈,不对不对,你这个adapter还没讲呢,对吼,那赶紧的跟上步伐
说说我这个牛X的adapter,所有项目的RecycleView都只需要这一个adapter就可以搞定了,如果item需要复杂的处理,可以拓展BaseViewHolder方法,主要思路就是,将数据交给adapter,adapter不做处理,只是对数据的size进行排版item,数据的设置回调给Activity去实现,Activity拿到数据去BaseViewHolder里面去设置界面显示数据,adapter里面实现了单击和长单击事件,和我之前那篇博文一样的思路,那来看看代码吧
BaseRecycleAdapter.java
这一次adapter的修改,主要是对当初的抽象onBindViewHolder方法变成了接口回调,当初需要继承这个Base,然后实现这个convert方法来对数据进行操作,但这个时候感觉继承这个adapter的使用者,完全不需要那么多的操作,只是对数据操作了下,大功能基本上是在BaseViewHolder处理,这一次整改,将这个设置器交给Activity来处理,还有就是数据的泛型,上一遍博文让所有的Model都继承BaseBean,这个真是多此一举啊,哎,失败,这里我给改成Object,方便传递,其他的和我上篇博文一样,可以看看,文章开头给了链接地址。
然后来看看BaseViewHolder.java
这里面的方法是需要开发者根据需求自己去定制添加方法的,我这里只是列举了一些常见的,大家可以自己扩展,大家可能看到我给的回调,如果你当前界面不需要设置监听,你完全可以直接调用设置数据源的方法,如果你需要item的子View触发事件,也可以调用有回调接口的方法,这个回调也是交给Activity去处理
来看看完整的MainActivity的代码
看完后有没有为之一振的感觉呢,Activity不去管那些复杂的操作,只做一些简单结果处理,确实有那么点意思,adapter也只需要给xml布局和数据源,不再去管理复杂操作,想怎么玩就怎么玩,所有项目的RecycleView都可以用这一个adapter,Activity立马解决数据操作,神器,绝对的神器,为了实现效果早点装逼,代码质量还需要一些规范分类(关键是懒,哈哈),里面用了好多的接口回调,也是醉了,不过这种结果处理,真是屡试不爽啊,好咯,下午马上就要上实验课了,作业还一大堆,不会操作就只会下位来装逼指导学生,每天上课之前ppt放映到”系主任”几个字的那个页面,真是受够了——————————愤青少年
最后附上github项目链接来star吧
好了,今天来一个更牛逼的神器RefreshLayout
效果图:
实现了上拉刷新和下拉加载功能
封装好的BaseAdapter和BaseViewHolder,将adapter交给Activity来管理
实现了单击事件和长单击事件
类结构图:
这个demo我把之前的BaseAdapter和BaseViewHolder的封装都重新整理了一边,然后把BaseAdapter抽象给Activity来管理,因为我发现我在之前的博文中封装的BaseAdapter,然后让其他的adapter去继承他去操作,这个adapter根本就不需要多少的操作,而且有点冗余,好多的adapter,烦,所以我打算把BaseAdapter的管理交给Activity去实现,这样,整个项目只需要一个BaseAdapter和BaseViewHolder去操作就行了,真的是万能的适配器啊,项目瞬间清爽了起来。好了,今天先来说说实现思路:
因为下拉加载SwipeRefreshLayout大家都知道的,官方的,没什么好讲,但是在处理上拉加载的时候这个下拉在后面还需要去处理,所以,先来讲上拉加载更多。
上拉加载更多需要哪些实现呢?
计算所有的RecycleView的item数量(即layoutManager.getItemCount())
获取当前页面底部可见的item的position位置(即LayoutManager.findLastVisibleItemPosition())
判断这个可见的position是否大于等于RecycleView的item数量减1(因为position是从0开始的)
我们还需要一个getChildCount辅助方法,获取当前整个屏幕显示的item数量,目的是判断有无item,来处理item不满一屏幕的时候处理。
当数据不满一屏幕的时候,SwipeRefreshLayout下拉的时候会触发我在onScrollStateChanged里面做的判断,然而这个判断是满足上拉加载更多的,会出现上拉加载刷新和下拉加载更多同时调用,然后看见数据突然的闪一下恢复到原来的数据,为了解决数据不满一屏的操作的bug,我在onTouch里面做了一个手势的处理,如果是向下拉,则给上拉加载更多的判断设置个flag为false,不让他去处理,亲测完美解决。
上代码,来看看RefreshRecycleView.java
/** * Created by wangqi on 2016/11/8. */ public class RefreshRecycleView extends RecyclerView { public RefreshRecycleView(Context context) { super(context); initView(context); } public RefreshRecycleView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initView(context); } public RefreshRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(context); } private ProgressDialog progressDialog; private void initView(Context context) { progressDialog = new ProgressDialog(context); progressDialog.setMessage("加载更多..."); } @Override public void onScrollStateChanged(int state) { super.onScrollStateChanged(state); //获取在各个不同的LayoutManager中可见的position位置 if (state == RecyclerView.SCROLL_STATE_IDLE && loadMoreListner != null && loadingMoreEnabled) { LayoutManager layoutManager = getLayoutManager(); int lastVisibleItemPosition; if (layoutManager instanceof GridLayoutManager) { lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()]; ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into); lastVisibleItemPosition = findMax(into); } else { lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); } //触发加载更多事件 if (flag && loadingMoreEnabled && layoutManager.getChildCount() > 0 && lastVisibleItemPosition >= layoutManager.getItemCount() - 1 && layoutManager.getItemCount() >= layoutManager.getChildCount()) { progressDialog.show(); loadMoreListner.onLoad(); } } } public boolean flag; float startY = 0; float moveY = 0; /** * * @param e * @return 处理数据不满一屏的手势判断 */ @Override public boolean onTouchEvent(MotionEvent e) { switch (e.getAction()) { case MotionEvent.ACTION_DOWN: startY = e.getRawY(); break; case MotionEvent.ACTION_MOVE: moveY = e.getRawY(); if (moveY > startY) flag = false; else flag = true; startY = moveY; break; case MotionEvent.ACTION_UP: break; } return super.onTouchEvent(e); } public void setLoadMoreComplete() { progressDialog.dismiss(); } //设置不给上拉加载 public void setLoadingMoreEnabled(boolean loadingMoreEnabled) { this.loadingMoreEnabled = loadingMoreEnabled; } private int findMax(int[] lastPositions) { int max = lastPositions[0]; for (int value : lastPositions) { if (value > max) { max = value; } } return max; } boolean loadingMoreEnabled = true; LoadMoreListner loadMoreListner; public void setLoadMoreListner(LoadMoreListner loadMoreListner) { this.loadMoreListner = loadMoreListner; } public interface LoadMoreListner { void onLoad(); } }
代码特别简单,
在滑动事件里面去判断当前上否是滑动状态,然后判断上拉加载更多是否可用,当前的回调是否已经注册。
获取RecycleView在不同LayoutManager的时候返回的底部可见的position的位置
layoutManager.getChildCount()是获取当前可见界面的item数量
lastVisibleItemPosition获取item可见的最底部的position位置
layoutManager.getItemCount()是获取整个RecycleView的item的总数
然后对当前进行判断,
falg是处理onTouch返回的数据不满一屏幕的判断,
其他的判断大家看看就懂的,不难
然后显示dialog,回调load接口,给别人去处理
好了,这时候来看看包装RefreshRecycleView的类RefreshLayout.java了
看看xml就懂了
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/refresh_swip" android:layout_width="match_parent" android:layout_height="match_parent"> <com.e8net.myapplication.RefreshRecycleView android:id="@+id/refresh_recycler" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v4.widget.SwipeRefreshLayout>
RefreshLayout只是对RecycleView的一种包装,专门处理上拉刷新和下拉加载更多,将所有事件的处理通过这个辅助类传递给Activity的调用者,外者只需要调用,不需要管理实现原理,简洁了代码。来看看代码
/** * Created by wangqi on 2016/11/8. */ public class RefreshLayout extends LinearLayout { RefreshRecycleView refreshRecycleView; SwipeRefreshLayout swipeRefreshLayout; public RefreshLayout(Context context) { super(context); initView(context); } public RefreshLayout(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public RefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } private void initView(final Context context) { View v = LayoutInflater.from(context).inflate(R.layout.refresh_view, this, false); refreshRecycleView = (RefreshRecycleView) v.findViewById(R.id.refresh_recycler); swipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.refresh_swip); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); this.addView(v, params); swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { onRefreshListner.refresh(); } }); //加载更多 refreshRecycleView.setLoadMoreListner(new RefreshRecycleView.LoadMoreListner() { @Override public void onLoad() { onRefreshListner.loadMore(); } }); } public void setLoadingMoreEnabled(boolean flag) { refreshRecycleView.setLoadingMoreEnabled(flag); } public void setLayoutManager(RecyclerView.LayoutManager layoutManager) { refreshRecycleView.setLayoutManager(layoutManager); } public void setAdapter(RecyclerView.Adapter<BaseViewHolder> adapter) { refreshRecycleView.setAdapter(adapter); } public void setRefreshComplete() { swipeRefreshLayout.setRefreshing(false); } public void setLoadMoreComplete() { refreshRecycleView.setLoadMoreComplete(); } private RefreshListner onRefreshListner; public void setOnRefreshListner(RefreshListner onRefreshListner) { this.onRefreshListner = onRefreshListner; } public interface RefreshListner { void refresh(); void loadMore(); } }
初始化xml,将view界面inflater到RefreshLayout
给下拉刷新和上拉加载进行注册
然后设置下拉刷新完成和上拉加载完成,这个大家应该都懂的,全是包装
然后注册个接口,将下拉和上拉的触发交个回调者来处理
这时候包装都结束了,最后来看看Activity来调用看看
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); refreshLayout = (RefreshLayout) findViewById(R.id.refresh_layout); list = new ArrayList<>(); addList(); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); refreshLayout.setLayoutManager(layoutManager); myRecycleAdapter = new BaseRecycleAdapter(this, R.layout.recycle_item, list); refreshLayout.setAdapter(myRecycleAdapter); refreshLayout.setOnRefreshListner(new RefreshLayout.RefreshListner() { @Override public void refresh() { refreshLayout.postDelayed(new Runnable() { @Override public void run() { list.clear(); addList(); myRecycleAdapter.notifyDataSetChanged(); refreshLayout.setRefreshComplete(); } }, 2000); } @Override public void loadMore() { refreshLayout.postDelayed(new Runnable() { @Override public void run() { addList(); myRecycleAdapter.notifyDataSetChanged(); refreshLayout.setLoadMoreComplete(); } }, 2000); } }); } public void addList() { for (int i = 0; i < 10; i++) list.add(""); }
下拉和上拉就这么搞定了,哈哈,不对不对,你这个adapter还没讲呢,对吼,那赶紧的跟上步伐
说说我这个牛X的adapter,所有项目的RecycleView都只需要这一个adapter就可以搞定了,如果item需要复杂的处理,可以拓展BaseViewHolder方法,主要思路就是,将数据交给adapter,adapter不做处理,只是对数据的size进行排版item,数据的设置回调给Activity去实现,Activity拿到数据去BaseViewHolder里面去设置界面显示数据,adapter里面实现了单击和长单击事件,和我之前那篇博文一样的思路,那来看看代码吧
BaseRecycleAdapter.java
/** * Created by wangqi on 2016/7/16. */ public class BaseRecycleAdapter extends RecyclerView.Adapter<BaseViewHolder> { private int layoutId; private List<? extends Object> data; public Context context; private OnItemClickListner onItemClickListner;//单击事件 private OnItemLongClickListner onItemLongClickListner;//长按单击事件 private boolean clickFlag = true;//单击事件和长单击事件的屏蔽标识 /** * @param context //上下文 * @param layoutId //布局id * @param data //数据源 */ public BaseRecycleAdapter(Context context, int layoutId, List<? extends Object> data) { this.layoutId = layoutId; this.data = data; this.context = context; } @Override public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(context).inflate(layoutId, parent, false); final BaseViewHolder holder = new BaseViewHolder(v, context); //单击事件回调 v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onItemClickListner == null) return; if (clickFlag) { onItemClickListner.onItemClickListner(v, holder.getLayoutPosition()); } clickFlag = true; } }); //单击长按事件回调 v.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (onItemLongClickListner == null) return false; onItemLongClickListner.onItemLongClickListner(v, holder.getLayoutPosition()); clickFlag = false; return false; } }); return holder; } @Override public void onBindViewHolder(BaseViewHolder holder, int position) { if (mCallBack != null) mCallBack.convert(holder, data.get(position), position); } @Override public int getItemCount() { return data.size(); } public void setOnItemClickListner(OnItemClickListner onItemClickListner) { this.onItemClickListner = onItemClickListner; } public void setOnItemLongClickListner(OnItemLongClickListner onItemLongClickListner) { this.onItemLongClickListner = onItemLongClickListner; } public interface OnItemClickListner { void onItemClickListner(View v, int position); } public interface OnItemLongClickListner { void onItemLongClickListner(View v, int position); } CallBack mCallBack; public void setCallBack(CallBack CallBack) { this.mCallBack = CallBack; } public interface CallBack { <T extends Object> void convert(BaseViewHolder holder, T bean, int position); } }
这一次adapter的修改,主要是对当初的抽象onBindViewHolder方法变成了接口回调,当初需要继承这个Base,然后实现这个convert方法来对数据进行操作,但这个时候感觉继承这个adapter的使用者,完全不需要那么多的操作,只是对数据操作了下,大功能基本上是在BaseViewHolder处理,这一次整改,将这个设置器交给Activity来处理,还有就是数据的泛型,上一遍博文让所有的Model都继承BaseBean,这个真是多此一举啊,哎,失败,这里我给改成Object,方便传递,其他的和我上篇博文一样,可以看看,文章开头给了链接地址。
然后来看看BaseViewHolder.java
/** * Created by wangqi on 2016/7/16. */ public class BaseViewHolder extends RecyclerView.ViewHolder { View convertView; Context context; public BaseViewHolder(View itemView, Context context) { super(itemView); this.convertView = itemView; this.context = context; } public View getItemView() { return convertView; } public void setText(int id, String text) { TextView tx = (TextView) convertView.findViewById(id); tx.setText(text); } public void setText(int id, String text, final OnClickListener onClickListener) { TextView tx = (TextView) convertView.findViewById(id); tx.setText(text); tx.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickListener.onClickListner(v); } }); } public void setImageListner(int id, final OnClickListener onClickListener) { ImageView img = (ImageView) convertView.findViewById(id); img.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickListener.onClickListner(v); } }); } public void setImageResource(int id, int resouceId) { ImageView img = (ImageView) convertView.findViewById(id); img.setImageResource(resouceId); } public void setImageResource(int id, int resouceId, final OnClickListener onClickListener) { ImageView img = (ImageView) convertView.findViewById(id); img.setImageResource(resouceId); img.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickListener.onClickListner(v); } }); } public interface OnClickListener { void onClickListner(View v); } }
这里面的方法是需要开发者根据需求自己去定制添加方法的,我这里只是列举了一些常见的,大家可以自己扩展,大家可能看到我给的回调,如果你当前界面不需要设置监听,你完全可以直接调用设置数据源的方法,如果你需要item的子View触发事件,也可以调用有回调接口的方法,这个回调也是交给Activity去处理
来看看完整的MainActivity的代码
public class MainActivity extends AppCompatActivity { private RefreshLayout refreshLayout; List<String> list; BaseRecycleAdapter myRecycleAdapter; public void addList() { for (int i = 0; i < 10; i++) list.add(""); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); refreshLayout = (RefreshLayout) findViewById(R.id.refresh_layout); list = new ArrayList<>(); addList(); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); refreshLayout.setLayoutManager(layoutManager); myRecycleAdapter = new BaseRecycleAdapter(this, R.layout.recycle_item, list); refreshLayout.setAdapter(myRecycleAdapter); refreshLayout.setOnRefreshListner(new RefreshLayout.RefreshListner() { @Override public void refresh() { refreshLayout.postDelayed(new Runnable() { @Override public void run() { list.clear(); addList(); myRecycleAdapter.notifyDataSetChanged(); refreshLayout.setRefreshComplete(); } }, 2000); } @Override public void loadMore() { refreshLayout.postDelayed(new Runnable() { @Override public void run() { addList(); myRecycleAdapter.notifyDataSetChanged(); refreshLayout.setLoadMoreComplete(); } }, 2000); } }); myRecycleAdapter.setOnItemClickListner(new BaseRecycleAdapter.OnItemClickListner() { @Override public void onItemClickListner(View v, int position) { Toast.makeText(MainActivity.this, "click---" + position, Toast.LENGTH_SHORT).show(); } }); myRecycleAdapter.setOnItemLongClickListner(new BaseRecycleAdapter.OnItemLongClickListner() { @Override public void onItemLongClickListner(View v, int position) { Toast.makeText(MainActivity.this, "longClick---" + position, Toast.LENGTH_SHORT).show(); } }); myRecycleAdapter.setCallBack(new BaseRecycleAdapter.CallBack() { @Override public <T> void convert(BaseViewHolder holder, T bean, final int position) { holder.setText(R.id.txt, "明天会更好" + position, new BaseViewHolder.OnClickListener() { @Override public void onClickListner(View v) { Toast.makeText(MainActivity.this, "明天会更好" + position, Toast.LENGTH_SHORT).show(); } }); holder.setImageListner(R.id.img, new BaseViewHolder.OnClickListener() { @Override public void onClickListner(View v) { Toast.makeText(MainActivity.this, "img" + position, Toast.LENGTH_SHORT).show(); } }); } }); } }
看完后有没有为之一振的感觉呢,Activity不去管那些复杂的操作,只做一些简单结果处理,确实有那么点意思,adapter也只需要给xml布局和数据源,不再去管理复杂操作,想怎么玩就怎么玩,所有项目的RecycleView都可以用这一个adapter,Activity立马解决数据操作,神器,绝对的神器,为了实现效果早点装逼,代码质量还需要一些规范分类(关键是懒,哈哈),里面用了好多的接口回调,也是醉了,不过这种结果处理,真是屡试不爽啊,好咯,下午马上就要上实验课了,作业还一大堆,不会操作就只会下位来装逼指导学生,每天上课之前ppt放映到”系主任”几个字的那个页面,真是受够了——————————愤青少年
最后附上github项目链接来star吧
相关文章推荐
- 安卓,采用最简单易懂的方式实现上拉刷新下拉加载更多
- 下拉刷新,上拉加载实现简介
- 上拉加载、下拉刷新功能实现
- RecyclerView之下拉刷新、下拉加载的实现
- 使用Android开源工具PullToRefresh实现上啦刷新下拉加载
- 安卓,采用最简单易懂的方式实现上拉刷新下拉加载更多
- 实现官方下拉刷新,增加自动加载更多
- 使用自定义的item、Adapter和AsyncTask、第三方开源框架PullToRefresh联合使用实现自定义的下拉列表(从网络加载图片显示在item中的ImageView)
- 安德鲁斯,最直接的方法,实现了上拉刷新下拉加载很多其他的
- XRecyclerView实现RecyclerView下拉刷新上来加载 自己做了部分修改,使代码更简洁易用
- 安卓PullToRefresh自动下拉加载刷新实现
- 自己实现网易新闻头条遇到的问题__坐标错误,上啦刷新下拉加载崩溃
- Android自定义View之快速实现下拉刷新, 点击加载更多ListView
- 一步一步实现ListView加载网络数据,下滑底部加载,顶部下拉刷新。并配有双缓存
- 实现app上对csdn的文章列表上拉刷新下拉加载以及加入缓存文章列表的功能 (制作csdn app 四)
- 实现app上对csdn的文章列表上拉刷新下拉加载以及加入缓存文章列表的功能 (制作csdn app 四)
- jQuery+AJAX实现无刷新下拉加载更多
- Android-PullToRefresh库实现上拉刷新下拉加载
- BaseAdapter<T> 重写 createViewFromResource实现界面,刷新,加载,移除
- Android下拉加载,上拉刷新的实现