不尝世间醋与墨,怎知人间酸与苦。

择一业谋食养命,等一运扭转乾坤。

你见过哪些令你膛目结舌的代码技巧?

文章目录

不尝世间醋与墨,怎知人间酸与苦。择一业谋食养命,等一运扭转乾坤。你见过哪些令你膛目结舌的代码技巧?

一,定义二,优点三,角色四,PositionalDataSource来源的使用1,添加依赖2,创建bean类3,创建PositionalDataSource来源的数据源4,创建数据工厂5,创建ViewModel6,创建adapter7,运行效果

五,ItemKeyedDataSource来源的使用1,创建数据仓库2,创建ItemKeyedDataSource3,创建YuanZhenDataSourceFactory

六,PageKeyedDataSource来源的使用1,创建PageKeyedDataSource2,创建数据工厂

一,定义

在我们的 Android 项目中使用 RecyclerViews 时,我们会显示一个包含很多项目的列表。有时我们有一些用例,比如从手机中获取联系人列表并将其显示在列表中。在列表中一次加载大量数据并不是一项非常有效的任务。为了克服这个问题,我们在 Android 中进行了分页。 Paging就是google为了分页而推出的一个库。Paging库可以帮助您一次加载和显示多个小的数据块,按需载入部分数据可以减少网络宽带和系统资源的使用量。

二,优点

①:分页库可以更加轻松地在应用程序中的Recyclerview逐步和优雅的加载数据 ​②:数据请求消耗的网络带宽更少,系统资源更少 ​③:即使在数据更新和刷新期间,应用程序仍会继续快速响应用户输入 ​ ④:不过多浪费,显示多少就用多少

三,角色

①:DataSource(数据源,包含了多种形式,例如:Room来源,PositionalDataSource来源,PageKeyedDataSource来源,ItemKeyedDataSource来源) 数据源就是数据的来源,可以有多种来源渠道,例如:“网络数据”,“本地数据”,“数据库数据”

②:PagedList(UIModel数据层,通过Factory的方式拿到数据源) 创建 管理 数据源 的工厂,为什么有一个工厂,除了可以去创建数据源之外,为了后续的扩展

③:PagedAdapter(不再是之前使用RecycleView的那种适配器了,而是和Paging配套的PagedListAdapter) 数据模型其实就是 ViewModel,用来管理数据 PagedList: 数据源获取的数据最终靠PagedList来承载。 对于PagedList,我们可以这样来理解,它就是一页数据的集合。 每请求一页,就是新的一个PagedList对象。

④:RecycleView(我们之前一直用的RecycleView,只不过setAdapter的时候,绑定的适配器是 PagedAdapter) 这个Adapter就是一个RecyclerView的Adapter。 不过我们在使用paging实现RecyclerView的分页加载效果, 不能直接继承RecyclerView的Adapter,而是需要继承PagedListAdapter。 LiveData观察到的数据,把感应到的数据 给 适配器,适配器又绑定了 RecyclerView,那么RecyclerView的列表数据就改变了

四,PositionalDataSource来源的使用

1,添加依赖

implementation 'androidx.paging:paging-runtime:2.1.0'

2,创建bean类

public class YuanZhen {

private String id;

private String name;

private String age;

public void setId(String id) {

this.id = id;

}

public String getId() {

return id;

}

public void setName(String name) {

this.name = name;

}

public void setAge(String age) {

this.age = age;

}

public String getName() {

return name;

}

public String getAge() {

return age;

}

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

YuanZhen student = (YuanZhen) o;

return id.equals(student.id) &&

name.equals(student.name) &&

age.equals(student.age);

}

// 比较的函数

@RequiresApi(api = Build.VERSION_CODES.KITKAT)

@Override

public int hashCode() {

return Objects.hash(id, name, age);

}

}

3,创建PositionalDataSource来源的数据源

public class YuanZhenDataSource extends PositionalDataSource {

/**

* 加载第一页数据的时候,会执行此函数来完成

* 加载初始化数据,加载的是第一页的数据。

* 形象的说,当我们第一次打开页面,需要回调此方法来获取数据。

*/

@Override

public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) {

callback.onResult(getStudents(0, 20), 0, 1000);

}

/**

* 当有了初始化数据之后,滑动的时候如果需要加载数据的话,会调用此方法。

*/

@Override

public void loadRange(@NonNull LoadRangeParams params, @NonNull LoadRangeCallback callback) {

callback.onResult(getStudents(params.startPosition, params.loadSize));

}

/**

* 数据源,数据的来源(数据库,文件,网络服务器响应 等等)

*/

private List getStudents(int startPosition, int pageSize) {

List list = new ArrayList<>();

for (int i = startPosition; i < startPosition + pageSize; i++) {

YuanZhen yuanZhen = new YuanZhen();

yuanZhen.setName("袁震:" + i);

yuanZhen.setAge("年龄:" + i);

list.add(yuanZhen);

}

return list;

}

}

4,创建数据工厂

public class YuanZhenDataSourceFactory extends DataSource.Factory {

@NonNull

@Override

public DataSource create() {

YuanZhenDataSource yuanZhenDataSource =new YuanZhenDataSource();

return yuanZhenDataSource;

}

}

5,创建ViewModel

public class YuanZhenViewModel extends ViewModel {

private final LiveData> listLiveData;

public YuanZhenViewModel() {

YuanZhenDataSourceFactory factory = new YuanZhenDataSourceFactory();

// 初始化 ViewModel

this.listLiveData = new LivePagedListBuilder(factory, 20).build();

}

public LiveData> getListLiveData() {

return listLiveData;

}

}

6,创建adapter

public class RecyclerPagingAdapter extends PagedListAdapter {

private static DiffUtil.ItemCallback DIFF_STUDNET = new

DiffUtil.ItemCallback() {

// 一般是比较 唯一性的内容, ID

@Override

public boolean areItemsTheSame(@NonNull YuanZhen oldItem, @NonNull YuanZhen newItem) {

return oldItem.getId().equals(newItem.getId());

}

// 对象本身的比较

@Override

public boolean areContentsTheSame(@NonNull YuanZhen oldItem, @NonNull YuanZhen newItem) {

return oldItem.equals(newItem);

}

};

protected RecyclerPagingAdapter() {

super(DIFF_STUDNET);

}

@NonNull

@Override

public MyRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, null);

return new MyRecyclerViewHolder(view);

}

@Override

public void onBindViewHolder(@NonNull MyRecyclerViewHolder holder, int position) {

YuanZhen yuanzhen = getItem(position);

// item view 出来了, 分页库还在加载数据中,我就显示 Id加载中

if (null == yuanzhen) {

holder.tvName.setText("Name加载中");

holder.tvAge.setText("age加载中");

} else {

holder.tvName.setText(yuanzhen.getName());

holder.tvAge.setText(yuanzhen.getAge());

}

}

// Item 优化的 ViewHolder

public static class MyRecyclerViewHolder extends RecyclerView.ViewHolder {

TextView tvId;

TextView tvName;

TextView tvAge;

public MyRecyclerViewHolder(View itemView) {

super(itemView);

tvName = itemView.findViewById(R.id.tv_name); // 名称

tvAge = itemView.findViewById(R.id.tv_age); // 性别

}

}

}

item

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="horizontal"

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:id="@+id/tv_name"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:textSize="20dp"

android:layout_weight="1"

android:gravity="center"

android:layout_marginLeft="5dp"

/>

android:id="@+id/tv_age"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:textSize="20dp"

android:textColor="@android:color/black"

android:layout_weight="1"

android:gravity="center"

android:layout_marginLeft="5dp"

/>

7,使用

public class MainActivity extends AppCompatActivity {

private RecyclerView recyclerView;

RecyclerPagingAdapter recyclerPagingAdapter;

YuanZhenViewModel viewModel;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

recyclerView = findViewById(R.id.recycle_view);

recyclerPagingAdapter = new RecyclerPagingAdapter();

viewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory())

.get(YuanZhenViewModel.class);

// LiveData 观察者 感应更新

viewModel.getListLiveData().observe(this, new Observer>() {

@Override

public void onChanged(PagedList students) {

// 再这里更新适配器数据

recyclerPagingAdapter.submitList(students);

}

});

recyclerView.setAdapter(recyclerPagingAdapter);

recyclerView.setLayoutManager(new LinearLayoutManager(this));

}

}

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"

tools:context=".MainActivity"

android:orientation="vertical">

android:id="@+id/recycle_view"

android:layout_width="match_parent"

android:layout_height="match_parent" />

7,运行效果

五,ItemKeyedDataSource来源的使用

1,创建数据仓库

public class DataRepository {

private List dataList = new ArrayList<>();

public DataRepository() {

for (int i = 0; i < 1000; i++) {

YuanZhen person = new YuanZhen();

person.setName("袁震:" + i);

person.setAge("年龄:" + i);

dataList.add(person);

}

}

public List initData(int size) {

return dataList.subList(0, size);

}

public List loadPageData(int page, int size) {

int totalPage;

if (dataList.size() % size == 0) {

totalPage = dataList.size() / size;

} else {

totalPage = dataList.size() / size + 1;

}

if (page > totalPage || page < 1) {

return null;

}

if (page == totalPage) {

return dataList.subList((page - 1) * size, dataList.size());

}

return dataList.subList((page - 1) * size, page * size);

}

}

2,创建ItemKeyedDataSource

public class CustomItemDataSource extends ItemKeyedDataSource {

private DataRepository dataRepository;

CustomItemDataSource(DataRepository dataRepository) {

this.dataRepository = dataRepository;

}

// loadInitial 初始加载数据

@Override

public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) {

List dataList = dataRepository.initData(params.requestedLoadSize);

callback.onResult(dataList);

}

@NonNull

@Override

public Integer getKey(@NonNull YuanZhen item) {

return (int) System.currentTimeMillis();

}

// loadBefore 向前分页加载数据

@Override

public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) {

List dataList = dataRepository.loadPageData(params.key, params.requestedLoadSize);

if (dataList != null) {

callback.onResult(dataList);

}

}

// loadAfter 向后分页加载数据

@Override

public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) {

List dataList = dataRepository.loadPageData(params.key, params.requestedLoadSize);

if (dataList != null) {

callback.onResult(dataList);

}

}

}

3,创建YuanZhenDataSourceFactory

public class YuanZhenDataSourceFactory extends DataSource.Factory {

@NonNull

@Override

public DataSource create() {

return new CustomItemDataSource(new DataRepository());

}

}

六,PageKeyedDataSource来源的使用

1,创建PageKeyedDataSource

public class CustomPageDataSource extends PageKeyedDataSource {

private DataRepository dataRepository;

CustomPageDataSource(DataRepository dataRepository) {

this.dataRepository = dataRepository;

}

// loadInitial 初始加载数据

@Override

public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) {

List dataList = dataRepository.initData(params.requestedLoadSize);

callback.onResult(dataList, null, 2);

}

// loadBefore 向前分页加载数据

@Override

public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) {

List dataList = dataRepository.loadPageData(params.key, params.requestedLoadSize);

if (dataList != null) {

callback.onResult(dataList, params.key - 1);

}

}

// loadAfter 向后分页加载数据

@Override

public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) {

List dataList = dataRepository.loadPageData(params.key, params.requestedLoadSize);

if (dataList != null) {

callback.onResult(dataList, params.key + 1);

}

}

}

2,创建数据工厂

public class YuanZhenDataSourceFactory extends DataSource.Factory {

@NonNull

@Override

public DataSource create() {

return new CustomPageDataSource(new DataRepository());

}

}

好文阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。