基于Android官方Paging Library的RecyclerView分页加载框架

来源:互联网 发布:电力施工预算软件 编辑:程序博客网 时间:2024/05/29 13:53


基于Android官方Paging Library的RecyclerView分页加载框架


我之前写了一篇RecyclerView分页加载机制的文章,是基于Android官方的AsyncListUtil实现的,详情见附录文章1。现在再介绍一种RecyclerView分页加载框架:Android Paging Library。
Android Paging Library是Android官方support-v7支持包中专门做的分页框架,详细文档见谷歌官方文档附录2页面。我写这篇文章时候Paging Library的版本是1.0.0-alpha3。
使用Android Paging Library首先需要在gradle添加引用:
[plain] view plain copy
print?
  1. implementation ‘android.arch.paging:runtime:1.0.0-alpha3’  
implementation 'android.arch.paging:runtime:1.0.0-alpha3'

下面我写示例代码做一个简单的演示:

[java] view plain copy
print?
  1. package zhangphil.demo;  
  2.   
  3. import android.arch.paging.PagedList;  
  4. import android.arch.paging.PagedListAdapter;  
  5. import android.arch.paging.TiledDataSource;  
  6. import android.graphics.Color;  
  7. import android.support.annotation.NonNull;  
  8. import android.support.v7.app.AppCompatActivity;  
  9. import android.os.Bundle;  
  10. import android.support.v7.recyclerview.extensions.DiffCallback;  
  11. import android.support.v7.widget.LinearLayoutManager;  
  12. import android.support.v7.widget.RecyclerView;  
  13. import android.text.TextUtils;  
  14. import android.util.Log;  
  15. import android.view.LayoutInflater;  
  16. import android.view.View;  
  17. import android.view.ViewGroup;  
  18. import android.widget.LinearLayout;  
  19. import android.widget.TextView;  
  20.   
  21. import java.util.ArrayList;  
  22. import java.util.List;  
  23. import java.util.concurrent.Executor;  
  24.   
  25. public class MainActivity extends AppCompatActivity {  
  26.     private PagedList<DataBean> mPagedList;  
  27.     private MyDataSource mDataSource;  
  28.   
  29.     private RecyclerView mRecyclerView;  
  30.     private PagedListAdapter mAdapter;  
  31.   
  32.     private LinearLayoutManager mLayoutManager;  
  33.   
  34.     @Override  
  35.     protected void onCreate(Bundle savedInstanceState) {  
  36.         super.onCreate(savedInstanceState);  
  37.         setContentView(R.layout.activity_main);  
  38.   
  39.         mDataSource = new MyDataSource();  
  40.         makePageList();  
  41.   
  42.         mRecyclerView = findViewById(R.id.recycler_view);  
  43.   
  44.         mLayoutManager = new LinearLayoutManager(this);  
  45.         mLayoutManager.setOrientation(LinearLayout.VERTICAL);  
  46.         mRecyclerView.setLayoutManager(mLayoutManager);  
  47.   
  48.         mAdapter = new MyAdapter();  
  49.         mRecyclerView.setAdapter(mAdapter);  
  50.   
  51.         mAdapter.setList(mPagedList);  
  52.   
  53.         mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {  
  54.             private int lastPos;  
  55.   
  56.             @Override  
  57.             public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  
  58.                 super.onScrollStateChanged(recyclerView, newState);  
  59.   
  60.                 lastPos = mLayoutManager.findLastVisibleItemPosition();  
  61.   
  62.                 mPagedList.loadAround(lastPos);//触发Android Paging的加载事务逻辑。  
  63.             }  
  64.         });  
  65.     }  
  66.   
  67.     private void makePageList() {  
  68.         PagedList.Config mPagedListConfig = new PagedList.Config.Builder()  
  69.                 .setPageSize(3//分页数据的数量。在后面的DataSource之loadRange中,count即为每次加载的这个设定值。  
  70.                 .setPrefetchDistance(5//初始化时候,预取数据数量。  
  71.                 .setEnablePlaceholders(false)  
  72.                 .build();  
  73.   
  74.         mPagedList = new PagedList.Builder()  
  75.                 .setConfig(mPagedListConfig)  
  76.                 .setDataSource(mDataSource)  
  77.                 .setMainThreadExecutor(new BackgroundThreadTask()) //初始化阶段启用  
  78.                 .setBackgroundThreadExecutor(new MainThreadTask()) //初始化阶段启动  
  79.                 .build();  
  80.     }  
  81.   
  82.     private class BackgroundThreadTask implements Executor {  
  83.         public BackgroundThreadTask() {  
  84.             this.execute(new Runnable() {  
  85.                 @Override  
  86.                 public void run() {  
  87.                     Log.d(”BackgroundThreadTask”“run”);  
  88.                 }  
  89.             });  
  90.         }  
  91.   
  92.         @Override  
  93.         public void execute(@NonNull Runnable runnable) {  
  94.             runnable.run();  
  95.         }  
  96.     }  
  97.   
  98.     private class MainThreadTask implements Executor {  
  99.         public MainThreadTask() {  
  100.             this.execute(new Runnable() {  
  101.                 @Override  
  102.                 public void run() {  
  103.                     Log.d(”MainThreadTask”“run”);  
  104.                 }  
  105.             });  
  106.         }  
  107.   
  108.         @Override  
  109.         public void execute(@NonNull Runnable runnable) {  
  110.             runnable.run();  
  111.         }  
  112.     }  
  113.   
  114.     private class MyDataSource extends TiledDataSource<DataBean> {  
  115.   
  116.         @Override  
  117.         public int countItems() {  
  118.             return TiledDataSource.COUNT_UNDEFINED;  
  119.         }  
  120.   
  121.         / 
  122.           注意,这里需要后台线程化。 
  123.           
  124.           @param startPosition 
  125.           @param count 
  126.           @return 
  127.          /  
  128.         @Override  
  129.         public List<DataBean> loadRange(int startPosition, int count) {  
  130.             Log.d(”MyDataSource”“loadRange:” + startPosition + “,” + count);  
  131.             List<DataBean> list = loadData(startPosition, count);  
  132.             return list;  
  133.         }  
  134.     }  
  135.   
  136.     / 
  137.       假设这里需要做一些后台线程的数据加载任务。 
  138.       
  139.       @param startPosition 
  140.       @param count 
  141.       @return 
  142.      /  
  143.     private List<DataBean> loadData(int startPosition, int count) {  
  144.         List<DataBean> list = new ArrayList();  
  145.   
  146.         for (int i = 0; i < count; i++) {  
  147.             DataBean data = new DataBean();  
  148.             data.id = startPosition + i;  
  149.             data.content = ”zhangphil@” + data.id;  
  150.             list.add(data);  
  151.         }  
  152.   
  153.         return list;  
  154.     }  
  155.   
  156.     private class MyViewHolder extends RecyclerView.ViewHolder {  
  157.         public TextView text1;  
  158.         public TextView text2;  
  159.   
  160.         public MyViewHolder(View itemView) {  
  161.             super(itemView);  
  162.   
  163.             text1 = itemView.findViewById(android.R.id.text1);  
  164.             text1.setTextColor(Color.RED);  
  165.   
  166.             text2 = itemView.findViewById(android.R.id.text2);  
  167.             text2.setTextColor(Color.BLUE);  
  168.         }  
  169.     }  
  170.   
  171.     private class MyAdapter extends PagedListAdapter<DataBean, MyViewHolder> {  
  172.         public MyAdapter() {  
  173.             super(mDiffCallback);  
  174.         }  
  175.   
  176.         @Override  
  177.         public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  178.             View view = LayoutInflater.from(getApplicationContext()).inflate(android.R.layout.simple_list_item_2, null);  
  179.             MyViewHolder holder = new MyViewHolder(view);  
  180.             return holder;  
  181.         }  
  182.   
  183.         @Override  
  184.         public void onBindViewHolder(MyViewHolder holder, int position) {  
  185.             DataBean data = mPagedList.get(position);  
  186.             holder.text1.setText(String.valueOf(position));  
  187.             holder.text2.setText(String.valueOf(data.content));  
  188.         }  
  189.     }  
  190.   
  191.     private DiffCallback<DataBean> mDiffCallback = new DiffCallback<DataBean>() {  
  192.   
  193.         @Override  
  194.         public boolean areItemsTheSame(@NonNull DataBean oldItem, @NonNull DataBean newItem) {  
  195.             Log.d(”DiffCallback”“areItemsTheSame”);  
  196.             return oldItem.id == newItem.id;  
  197.         }  
  198.   
  199.         @Override  
  200.         public boolean areContentsTheSame(@NonNull DataBean oldItem, @NonNull DataBean newItem) {  
  201.             Log.d(”DiffCallback”“areContentsTheSame”);  
  202.             return TextUtils.equals(oldItem.content, newItem.content);  
  203.         }  
  204.     };  
  205.   
  206.     private class DataBean {  
  207.         public int id;  
  208.         public String content;  
  209.     }  
  210. }  
package zhangphil.demo;

import android.arch.paging.PagedList;
import android.arch.paging.PagedListAdapter;
import android.arch.paging.TiledDataSource;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.recyclerview.extensions.DiffCallback;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

public class MainActivity extends AppCompatActivity {
private PagedList<DataBean> mPagedList;
private MyDataSource mDataSource;

private RecyclerView mRecyclerView;private PagedListAdapter mAdapter;private LinearLayoutManager mLayoutManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    mDataSource = new MyDataSource();    makePageList();    mRecyclerView = findViewById(R.id.recycler_view);    mLayoutManager = new LinearLayoutManager(this);    mLayoutManager.setOrientation(LinearLayout.VERTICAL);    mRecyclerView.setLayoutManager(mLayoutManager);    mAdapter = new MyAdapter();    mRecyclerView.setAdapter(mAdapter);    mAdapter.setList(mPagedList);    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {        private int lastPos;        @Override        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {            super.onScrollStateChanged(recyclerView, newState);            lastPos = mLayoutManager.findLastVisibleItemPosition();            mPagedList.loadAround(lastPos);//触发Android Paging的加载事务逻辑。        }    });}private void makePageList() {    PagedList.Config mPagedListConfig = new PagedList.Config.Builder()            .setPageSize(3) //分页数据的数量。在后面的DataSource之loadRange中,count即为每次加载的这个设定值。            .setPrefetchDistance(5) //初始化时候,预取数据数量。            .setEnablePlaceholders(false)            .build();    mPagedList = new PagedList.Builder()            .setConfig(mPagedListConfig)            .setDataSource(mDataSource)            .setMainThreadExecutor(new BackgroundThreadTask()) //初始化阶段启用            .setBackgroundThreadExecutor(new MainThreadTask()) //初始化阶段启动            .build();}private class BackgroundThreadTask implements Executor {    public BackgroundThreadTask() {        this.execute(new Runnable() {            @Override            public void run() {                Log.d("BackgroundThreadTask", "run");            }        });    }    @Override    public void execute(@NonNull Runnable runnable) {        runnable.run();    }}private class MainThreadTask implements Executor {    public MainThreadTask() {        this.execute(new Runnable() {            @Override            public void run() {                Log.d("MainThreadTask", "run");            }        });    }    @Override    public void execute(@NonNull Runnable runnable) {        runnable.run();    }}private class MyDataSource extends TiledDataSource&lt;DataBean&gt; {    @Override    public int countItems() {        return TiledDataSource.COUNT_UNDEFINED;    }    /**     * 注意,这里需要后台线程化。     *     * @param startPosition     * @param count     * @return     */    @Override    public List&lt;DataBean&gt; loadRange(int startPosition, int count) {        Log.d("MyDataSource", "loadRange:" + startPosition + "," + count);        List&lt;DataBean&gt; list = loadData(startPosition, count);        return list;    }}/** * 假设这里需要做一些后台线程的数据加载任务。 * * @param startPosition * @param count * @return */private List&lt;DataBean&gt; loadData(int startPosition, int count) {    List&lt;DataBean&gt; list = new ArrayList();    for (int i = 0; i &lt; count; i++) {        DataBean data = new DataBean();        data.id = startPosition + i;        data.content = "zhangphil@" + data.id;        list.add(data);    }    return list;}private class MyViewHolder extends RecyclerView.ViewHolder {    public TextView text1;    public TextView text2;    public MyViewHolder(View itemView) {        super(itemView);        text1 = itemView.findViewById(android.R.id.text1);        text1.setTextColor(Color.RED);        text2 = itemView.findViewById(android.R.id.text2);        text2.setTextColor(Color.BLUE);    }}private class MyAdapter extends PagedListAdapter&lt;DataBean, MyViewHolder&gt; {    public MyAdapter() {        super(mDiffCallback);    }    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(getApplicationContext()).inflate(android.R.layout.simple_list_item_2, null);        MyViewHolder holder = new MyViewHolder(view);        return holder;    }    @Override    public void onBindViewHolder(MyViewHolder holder, int position) {        DataBean data = mPagedList.get(position);        holder.text1.setText(String.valueOf(position));        holder.text2.setText(String.valueOf(data.content));    }}private DiffCallback&lt;DataBean&gt; mDiffCallback = new DiffCallback&lt;DataBean&gt;() {    @Override    public boolean areItemsTheSame(@NonNull DataBean oldItem, @NonNull DataBean newItem) {        Log.d("DiffCallback", "areItemsTheSame");        return oldItem.id == newItem.id;    }    @Override    public boolean areContentsTheSame(@NonNull DataBean oldItem, @NonNull DataBean newItem) {        Log.d("DiffCallback", "areContentsTheSame");        return TextUtils.equals(oldItem.content, newItem.content);    }};private class DataBean {    public int id;    public String content;}

}

代码实现的功能很简单,当RecyclerView不断下滑时,就触发分页加载,把RecyclerView后续使用的数据分页加载显示出来。暂时我将现阶段对Android Paging Library技术的心得记录下来,作为我学习Android Paging Library技术的阶段性备忘录。这部分代码还有待进一步完善,Android Paging Library技术细节后续会继续跟进研究。


附录:
1,《基于Android官方AsyncListUtil优化改进RecyclerView分页加载机制(一)》链接:http://blog.csdn.net/zhangphil/article/details/78603499&nbsp;
2,谷歌Android官方Android Paging Library技术文档主页:https://developer.android.google.cn/topic/libraries/architecture/paging.html#classes

转自:http://blog.csdn.net/zhangphil/article/details/78627332
阅读全文
0 0