查看: 1317|回复: 0

[手机开发] Android RecyclerView上拉加载和下拉刷新(基础版)

发表于 2017-8-1 08:00:04

这里讲述的是用谷歌原生的SwipeRefreshLayout,进行刷新,以及利用RecycleView的滚动事件,判断是否到最后一个item,进行加载更多,这里加载更多是在RecycleView的适配器中使用不同item进行完成的。

这是activity的xml布局:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical">
  7. <android.support.v4.widget.SwipeRefreshLayout
  8. android:id="@+id/swipe_refresh_layout"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. >
  12. <android.support.v7.widget.RecyclerView
  13. android:id="@+id/recyclerview"
  14. android:layout_width="match_parent"
  15. android:layout_height="match_parent"
  16. android:background="#F0F0F0"
  17. android:clipToPadding="false"
  18. android:paddingBottom="16dp"
  19. android:paddingTop="16dp"/>
  20. </android.support.v4.widget.SwipeRefreshLayout>
  21. <com.rey.material.widget.ProgressView
  22. android:id="@+id/progress_loading_main"
  23. app:pv_autostart="true"
  24. app:pv_circular="true" app:pv_progressStyle="@style/Material.Drawable.CircularProgress"
  25. app:pv_progressMode="indeterminate"
  26. android:layout_width="50dp"
  27. android:layout_height="50dp"
  28. android:visibility="gone"
  29. android:layout_centerInParent="true"/>
  30. </RelativeLayout>
复制代码

接下来是对应activity中的代码:

  1. import android.os.Bundle;
  2. import android.os.Handler;
  3. import android.support.annotation.Nullable;
  4. import android.support.design.widget.Snackbar;
  5. import android.support.v4.app.Fragment;
  6. import android.support.v4.widget.SwipeRefreshLayout;
  7. import android.support.v7.widget.LinearLayoutManager;
  8. import android.support.v7.widget.RecyclerView;
  9. import android.view.LayoutInflater;
  10. import android.view.View;
  11. import android.view.ViewGroup;
  12. import com.retrofit.wangfei.viewpagertablayout.util.Constance;
  13. import com.retrofit.wangfei.viewpagertablayout.R;
  14. import com.retrofit.wangfei.viewpagertablayout.adapter.MyRecycleViewAdapter;
  15. import com.rey.material.widget.ProgressView;
  16. import java.util.ArrayList;
  17. import java.util.List;
  18. import butterknife.Bind;
  19. import butterknife.ButterKnife;
  20. public class HomeFragment extends Fragment {
  21. @Bind(R.id.recyclerview)
  22. RecyclerView recyclerview;
  23. @Bind(R.id.swipe_refresh_layout)
  24. SwipeRefreshLayout swipeRefreshLayout;
  25. @Bind(R.id.progress_loading_main)
  26. ProgressView progress_loading_main; // 加载数据时显示的进度圆圈
  27. private LinearLayoutManager mRecycleViewLayoutManager;
  28. private int mPageNum = 1;
  29. private List<String> lists = new ArrayList<>();
  30. private MyRecycleViewAdapter mAdapter;
  31. public static HomeFragment newInstance() {
  32. HomeFragment fragment = new HomeFragment();
  33. return fragment;
  34. }
  35. @Override
  36. public void onCreate(Bundle savedInstanceState) {
  37. super.onCreate(savedInstanceState);
  38. }
  39. @Override
  40. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  41. Bundle savedInstanceState) {
  42. View view = inflater.inflate(R.layout.fragment_home, container, false);
  43. ButterKnife.bind(this, view);
  44. return view;
  45. }
  46. /**在onCreateView方法后执行*/
  47. @Override
  48. public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
  49. super.onViewCreated(view, savedInstanceState);
  50. mAdapter = new MyRecycleViewAdapter(lists,getActivity());
  51. initRecyclerView();
  52. swipeRefreshLayout.setColorSchemeResources(Constance.colors);//设置下拉刷新控件变换的四个颜色
  53. recyclerview.setAdapter(mAdapter);
  54. recyclerViewOnItemClickListener();
  55. refresh();
  56. loadMore(mAdapter);
  57. progress_loading_main.setVisibility(View.VISIBLE);
  58. initData();
  59. }
  60. @Override
  61. public void onDestroyView() {
  62. super.onDestroyView();
  63. ButterKnife.unbind(this);
  64. }
  65. /**进入页面的初始化数据*/
  66. private void initData(){
  67. new Handler().postDelayed(new Runnable() {
  68. @Override
  69. public void run() {
  70. netNewsList(true);
  71. progress_loading_main.setVisibility(View.GONE);
  72. }
  73. }, 2000);
  74. }
  75. /**RecyclerView每个item的点击事件*/
  76. private void recyclerViewOnItemClickListener() {
  77. mAdapter.setOnItemClickListener(new MyRecycleViewAdapter.OnItemClickListener() {
  78. @Override
  79. public void onItemClick(View view, int position) {
  80. Snackbar.make(view, "fly", Snackbar.LENGTH_SHORT).show();
  81. }
  82. });
  83. }
  84. /**
  85. * 初始化RecyclerView
  86. */
  87. private void initRecyclerView() {
  88. // recyclerview.setItemAnimator(new DefaultItemAnimator());
  89. // recyclerview.setHasFixedSize(true);
  90. mRecycleViewLayoutManager = new LinearLayoutManager(getActivity());
  91. recyclerview.setLayoutManager(mRecycleViewLayoutManager); // 设置RecycleView,显示是ListView还是gridView还是瀑布流
  92. }
  93. /**下拉刷新*/
  94. private void refresh() {
  95. swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
  96. @Override
  97. public void onRefresh() {
  98. new Handler().postDelayed(new Runnable() {
  99. @Override
  100. public void run() {
  101. netNewsList(true);
  102. swipeRefreshLayout.setRefreshing(false); // 停止刷新
  103. }
  104. }, 2000);
  105. }
  106. });
  107. }
  108. /**
  109. * 设置上拉加载更多
  110. *
  111. * @param adapter RecyclerView适配器
  112. */
  113. public void loadMore(final MyRecycleViewAdapter adapter) {
  114. recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
  115. private int lastVisibleItem;
  116. @Override
  117. public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  118. super.onScrolled(recyclerView, dx, dy);
  119. lastVisibleItem = mRecycleViewLayoutManager.findLastVisibleItemPosition(); // 滑动到最后一个
  120. }
  121. @Override
  122. public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  123. super.onScrollStateChanged(recyclerView, newState);
  124. // 效果在暂停时显示, 否则会导致重绘异常
  125. if (newState == RecyclerView.SCROLL_STATE_IDLE
  126. && lastVisibleItem + 1 == adapter.getItemCount()) {
  127. if (lists != null && lists.size() >= 10) { // 真实开发中要设置mNews.size()大于加载分页显示的个数
  128. adapter.loadLayout.setVisibility(View.VISIBLE);
  129. //加载更多
  130. new Handler().postDelayed(new Runnable() {
  131. @Override
  132. public void run() {
  133. netNewsList(false);
  134. }
  135. }, 2000);
  136. }
  137. }
  138. }
  139. });
  140. }
  141. /**
  142. * 从网络加载数据列表
  143. *
  144. * @param isRefresh 是否刷新 true 为刷新,false为不刷新
  145. */
  146. private void netNewsList(boolean isRefresh) {
  147. // viewDelegate.showLoading();
  148. if (isRefresh) {
  149. mPageNum = 1;
  150. } else {
  151. mPageNum++;
  152. }
  153. if (isRefresh) {
  154. if (!lists.isEmpty()) {
  155. lists.clear();
  156. }
  157. }
  158. // TODO 这里把页数mPageNum上传到服务端
  159. lists.clear();
  160. lists.addAll(getData());
  161. mAdapter.notifyDataSetChanged();
  162. }
  163. private List<String> list = new ArrayList<>();
  164. private List<String> getData() {
  165. for (int i = 0; i < 10; i++) {
  166. list.add(i + "");
  167. }
  168. return list;
  169. }
  170. }
复制代码

接下来是RecycleView适配器中的xml文件:

这是正常item的布局,至于用CardView是为了让item展示出来的效果更好看

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical" android:layout_width="match_parent"
  4. android:layout_height="wrap_content">
  5. <TextView
  6. android:id="@+id/text"
  7. android:layout_width="match_parent"
  8. android:layout_height="50dp"
  9. android:text=""
  10. android:gravity="center"/>
  11. </android.support.v7.widget.CardView>
复制代码

这是现实上拉加载的布局文件,作为不同item共同展示在RecycleView上面:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. android:id="@+id/load_layout"
  5. android:visibility="gone"
  6. android:layout_width="match_parent"
  7. android:layout_height="wrap_content"
  8. android:gravity="center"
  9. android:orientation="horizontal"
  10. android:paddingBottom="12dip"
  11. android:paddingTop="12dip">
  12. <com.rey.material.widget.ProgressView
  13. app:pv_autostart="true"
  14. app:pv_circular="true"
  15. app:pv_progressStyle="@style/Material.Drawable.CircularProgress"
  16. app:pv_progressMode="indeterminate"
  17. android:layout_width="24dp"
  18. android:layout_height="24dp" />
  19. <TextView
  20. android:id="@+id/more_data_msg"
  21. android:layout_width="wrap_content"
  22. android:layout_height="wrap_content"
  23. android:textSize="16sp"
  24. android:layout_marginLeft="10dp"
  25. android:text="正在加载..." />
  26. </LinearLayout>
复制代码

下面我们看看RecycleView适配器的写法:

  1. import android.app.Activity;
  2. import android.support.v7.widget.RecyclerView;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.LinearLayout;
  7. import android.widget.TextView;
  8. import com.retrofit.wangfei.viewpagertablayout.R;
  9. import java.util.List;
  10. import butterknife.Bind;
  11. import butterknife.ButterKnife;
  12. /**
  13. * Created by Android Studio
  14. * Description: RecycleView的适配器
  15. */
  16. public class MyRecycleViewAdapter extends RecyclerView.Adapter {
  17. private final static int TYPE_ITEM = 0X01;
  18. private final static int TYPE_FOOTER = 0x02;
  19. private List<String> lists;
  20. private Activity context;
  21. public LinearLayout loadLayout;
  22. private OnItemClickListener mOnItemClickListener; // 声明接口
  23. public MyRecycleViewAdapter(List<String> lists, Activity context) {
  24. this.lists = lists;
  25. this.context = context;
  26. }
  27. @Override
  28. public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  29. if (TYPE_ITEM == viewType) {
  30. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_item, parent,false);
  31. ItemViewHolder itemViewHolder = new ItemViewHolder(view);
  32. return itemViewHolder;
  33. } else {
  34. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_footer, parent,false);
  35. loadLayout = (LinearLayout) view.findViewById(R.id.load_layout);
  36. return new FootViewHolder(view);
  37. }
  38. }
  39. @Override
  40. public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
  41. if (holder instanceof ItemViewHolder) {
  42. String text = lists.get(position);
  43. ItemViewHolder itemHolder = (ItemViewHolder) holder;
  44. itemHolder.text.setText(text);
  45. }
  46. }
  47. @Override
  48. public int getItemCount() {
  49. return lists.size() + 1;
  50. }
  51. @Override
  52. public int getItemViewType(int position) {
  53. if (position + 1 == getItemCount()) {
  54. return TYPE_FOOTER;
  55. } else {
  56. return TYPE_ITEM;
  57. }
  58. }
  59. public class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
  60. @Bind(R.id.text)
  61. TextView text;
  62. public ItemViewHolder(View itemView) {
  63. super(itemView);
  64. ButterKnife.bind(this,itemView);
  65. itemView.setOnClickListener(this);
  66. }
  67. @Override
  68. public void onClick(View v) {
  69. mOnItemClickListener.onItemClick(v,getPosition());
  70. }
  71. }
  72. public class FootViewHolder extends RecyclerView.ViewHolder {
  73. public FootViewHolder(View itemView) {
  74. super(itemView);
  75. }
  76. }
  77. /**调到外部使用*/
  78. public void setOnItemClickListener(OnItemClickListener onItemClickListener){
  79. this.mOnItemClickListener = onItemClickListener;
  80. }
  81. /**定义接口*/
  82. public interface OnItemClickListener{
  83. void onItemClick(View v,int position);
  84. }
  85. }
复制代码

最后是刷新控件的4个不同颜色:

  1. public interface Constance {
  2. /**
  3. * 下拉刷新控件变化的四个颜色
  4. */
  5. int[] colors = new int[] {
  6. android.R.color.holo_green_light, android.R.color.holo_blue_light,
  7. android.R.color.holo_green_light, android.R.color.holo_blue_light
  8. };
  9. }
复制代码

所需要的依赖库:

  1. compile 'com.android.support:appcompat-v7:23.3.0'
  2. compile 'com.android.support:design:23.3.0'
  3. compile 'com.jakewharton:butterknife:7.0.1'
  4. compile 'com.android.support:support-v4:23.3.0'
  5. /**谷歌服务*/
  6. compile 'com.google.android.gms:play-services:8.4.0'
  7. compile 'com.github.rey5137:material:1.2.2'
复制代码

到这里就结束了,完成了下拉刷新和上拉加载更多的实现。

下面说说RecyclerView的使用最基础的三点:

一:

  1. recyclerview.setHasFixedSize(true);
  2. //方法用来使RecyclerView保持固定的大小,该信息被用于自身的优化。
复制代码

二:

recyclerview.setItemAnimator(new DefaultItemAnimator());
ItemAnimator会根据适配器上收到的通知动画显示视图组的修改。基本上,它会自动显示添加和移除条目动画。这也不是一个简单的类,但我们发现DefaultItemAnimator已经可以运行得很好了。

三:

  1. recyclerview.setLayoutManager(mRecycleViewLayoutManager);
  2. // 设置RecycleView,显示是ListView还是gridView还是瀑布流。
  3. // 显示是ListView
  4. LinearLayoutManager mRecycleViewLayoutManager = new LinearLayoutManager(context);
  5. // 显示是gridView,参数一:上下文,参数二:列数
  6. GridLayoutManager mGridLayoutManager=new GridLayoutManager(context, 4);
  7. // 显示是瀑布流,参数一:显示几列,参数二:现实的方向,垂直或水平
  8. StaggeredGridLayoutManager mStaggeredGridLayoutManager=new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
复制代码

更多详细请参考:Android RecyclerView艺术般的控件使用完全解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。



回复

使用道具 举报

关闭

站长推荐上一条 /1 下一条