zoukankan      html  css  js  c++  java
  • Android Architecture Components 系列(六)Paging Library

    Paging Library 分页加载库 
        用于逐步从数据源加载信息,而不会耗费过多的设备资源或是等待太长的时间。
     
    现有的分页加载功能的优点 mix 缺陷:
    CursorAdapter ,使得从数据库加载数据到ListVIew变得非常容易。
                                但是这是在主线程中查询数据库,并且分也的内容实用低效的Cursor返回。更多使用CursorAdapter带来的问题参考Large Database Queries on Android
    AsyncListUtils  ,提供基于位置的 分页加载到RecycleView中。
                                但是无法使用不基于位置 的分页加载,而且强制把null 作为占位符
     
     DataSource 数据源
        根据想要访问数据的方式,可以有两种子类可供选择:
            KeyedDataSource用于加载从第N到N+1 条数据
            TiledDataSource用于从任意位置的分页数据
     
        例如使用 Room persistence library就可以自动创建返回 TiledDataSource类型的数据:
     
       @Query("select * from users WHERE age > :age order by name DESC, id ASC")
    TiledDataSource<User> usersOlderThan(int age);
     
    PagedList 定量数据
       从上面DataSource 获取指定数量的数据,并且可以制定预取多少数据。这样可以最大程度减少加载数据的时间。
        ps:这个类提供更新信息给其他类 比如RecyclerView.Adapter来更新 RecyclerView的UI。
     
    PagedListAdapter 适配器
        这个类是RecyclerView.Adapter得到一个实现类,用于当数据加载完毕时,通知Recycle数据1已经到达可以进行加载显示。Recycleview就可以把数据填充进行显示操作。
     
    PagedListProvider
        从数据源中产生 LiveData<PagedList>。此外如果使用的是 Room persistence library,DAO还能使用 TiledDataSource生成 LivePagedListProvider。示例代码:
     
            @Query("SELECT * from users order WHERE age > :age order by name DESC, id ASC”)
         public abstract LivePagedListProvider<Integer, User> usersOlderThan(int age);
     
    Paging Library从后台线程获取数据流,再在Ui线程中展示就是通过以上几个重要类。
     
    流程图:
     
    当新的item插入到数据库,DataSource被更新,LivePagedListProvider在后台线程产生了新的PagedList
     
     
        继而,中间新生成的PagedList 在主线程中被发送到PagedListAdapter中,让它使用后台线程DiffUtil计算新的List和原来的List的差距,
    当差异比较完后,PagedListAdapter用RecyclerView.Adapter.notifyItemInserted()来通知数据刷新。
        
        实例代码:
     
    /**
    * Dao数据库操作
    */
    @Dao 
    interface UserDao{ 
        @Query("SELECT * FROM user ORDER BY lastName ASC”) 
        public abstractLivePagedListProvider<Integer, User>usersByLastName(); 
    /**
    * ViewModel 数据源
    */
    class MyViewModel extends ViewModel{ 
        public final LiveData<PagedList<User>> usersList ;//数据list 
        public MyViewModel(UserDao userDao) { 
            usersList =userDao.usersByLastName().create( 
               /* initial load position */ 0,
                 new PagedList.Config.Builder()
                         .setPageSize(50) 
                        .setPrefetchDistance(50) .build()); 
            }
     }
    /**
    *  View层的实现
    *  初始化ViewModel、RecycleView并绑定PagedListAdapter
    * 通过observe方法将ViewMode数据加载到数据List中
    */
     class MyActivity extends AppCompatActivity { 
           @Override 
            public void onCreate(Bundle savedState) { 
                super.onCreate(savedState); 
            MyViewModel viewModel = ViewModelProviders.of(this).get(MyViewModel.class); 
            RecyclerViewrecyclerView = findViewById(R.id.user_list); 
           UserAdapter<User> adapter= new UserAdapter();
             viewModel.usersList.observe(this,
                         pagedList -> adapter.setList(pagedList));
             recyclerView.setAdapter(adapter);
             } 
        } 
    /**
    *  PagedListAdapter 适配器配置
    *  覆写onBindViewHolder()方法
    *  @param UserViewHolder
    *  @param position
        
    */
    class UserAdapter extends PagedListAdapter<User, UserViewHolder> { 
            public UserAdapter() { 
                super(DIFF_CALLBACK);
            }
         
        @Override
        public void onBindViewHolder(UserViewHolder holder, int position) { 
            User user = getItem(position); //通过position 获取当条数据
            if (user != null) { 
                holder.bindTo(user); 
            } else { 
                // Null defines a placeholder item - PagedListAdapter will automatically invalidate
                 // this row when the actual object is loaded from the database 
                holder.clear(); 
            } 
        } 
     
    /**
    * 后台线程DiffUtil类回调: 计算新的List和原来的List的差距
    */
        public static final DiffCallback<User> DIFF_CALLBACK = new DiffCallback<User>() { 
                @Override 
                public boolean areItemsTheSame(@NonNull User oldUser, @NonNull User newUser) { 
                   // User properties may have changed if reloaded from the DB, but ID is fixed 
                    return oldUser.getId() == newUser.getId(); 
                } 
                @Override 
                public boolean areContentsTheSame(@NonNull User oldUser, @NonNull User newUser) { 
                    // NOTE: if you use equals, your object must properly override Object#equals() 
                    // Incorrectly returning false here will result in too many animations. 
                    return oldUser.equals(newUser); 
                } 
        } 
    }
     
     
    PS.鉴于大家的都建议给一个整体框架的demo,这里可以提供一个更好的方案:Google Android Architecture Components,这是Google官方提供的样例可以用来参考。
     
     
     
  • 相关阅读:
    webpack(二)
    webpack(一)
    初探Vue SSR(1)
    Node版本管理控制器n
    Gitlab用户在组中有五种权限:Guest、Reporter、Developer、Master、Owner
    微信小程序分享参数传递
    关于vue-cli3.*搭建项目遇到问题整理
    请求头出现provisional headers are shown 和 vue-cli 3.x配置跨域代理
    HDU6409 没有兄弟的舞会
    HDU6446 Tree and Permutation
  • 原文地址:https://www.cnblogs.com/cold-ice/p/9115858.html
Copyright © 2011-2022 走看看