暂时用不到,用到再来学
1.导入依赖
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.picasso:picasso:2.71828")
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
implementation("androidx.paging:paging-runtime:2.1.2")
网络权限
<uses-permission android:name="android.permission.INTERNET"/>
2.网络请求
package com.tiger.paging.api;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static final String BASE_URL = "http://192.168.202.55:8999/";
private static RetrofitClient mInstance;
private final Retrofit retrofit;
private RetrofitClient() {
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())//转化的是JSON
.client(getClient()).build();
}
private OkHttpClient getClient() {
return new OkHttpClient.Builder().build();
}
public static synchronized RetrofitClient getInstance(){
if (mInstance == null){
mInstance = new RetrofitClient();
}
return mInstance;
}
public Api getApi(){
return retrofit.create(Api.class);
}
}
package com.tiger.paging.api;
import com.tiger.paging.model.Movies;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface Api {
@GET("/findList")
Call<Movies> getMovies(
@Query("start") int start,
@Query("count") int count
);
}
3.model
package com.tiger.paging.model;
import java.util.Objects;
public class Movie {
public int id;
public String title;
public String rate;
public String cover;
@Override
public String toString() {
return "Movie{" +
"id=" + id +
", title='" + title + '\'' +
", rate='" + rate + '\'' +
", cover='" + cover + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Movie movie = (Movie) o;
return id == movie.id && title.equals(movie.title) && rate.equals(movie.rate) && cover.equals(movie.cover);
}
@Override
public int hashCode() {
return Objects.hash(id, title, rate, cover);
}
}
package com.tiger.paging.model;
import com.google.gson.annotations.SerializedName;
import java.util.List;
import java.util.Objects;
public class Movies {
private Integer count;
private Integer start;
//由JavaBind Jackson
private Integer total;
@SerializedName("subjects")
private List<Movie> movieList;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Movies movies = (Movies) o;
return Objects.equals(count, movies.count) && Objects.equals(start, movies.start) && Objects.equals(total, movies.total) && Objects.equals(movieList, movies.movieList);
}
@Override
public int hashCode() {
return Objects.hash(count, start, total, movieList);
}
@Override
public String toString() {
return "Movies{" +
"count=" + count +
", start=" + start +
", total=" + total +
", movieList=" + movieList +
'}';
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Integer getStart() {
return start;
}
public void setStart(Integer start) {
this.start = start;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public List<Movie> getMovieList() {
return movieList;
}
public void setMovieList(List<Movie> movieList) {
this.movieList = movieList;
}
}
4.页面 MovieDataSource
package com.tiger.paging.paging;
//positionDataSource
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.paging.PositionalDataSource;
import com.tiger.paging.api.RetrofitClient;
import com.tiger.paging.model.Movie;
import com.tiger.paging.model.Movies;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MovieDataSource extends PositionalDataSource<Movie> {
public static final int PER_PAGE = 8;
//页面首次加载数据会调用
@Override
public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback<Movie> callback) {
int startPosition = 0;
RetrofitClient.getInstance().getApi().getMovies(startPosition,PER_PAGE)
//加入到队列里
.enqueue(new Callback<Movies>() {
@Override
public void onResponse(Call<Movies> call, Response<Movies> response) {
if (response.body()!=null){
//把数据传递给PagedList
callback.onResult(response.body().getMovieList(),response.body().getStart(),response.body().getTotal());
Log.d("ning","loadInitial:"+response.body().getMovieList());
}
}
@Override
public void onFailure(Call<Movies> call, Throwable t) {
}
});
}
//加载下一页会调用 截至条件时返回空集
@Override
public void loadRange(@NonNull LoadRangeParams params, @NonNull LoadRangeCallback<Movie> callback) {
RetrofitClient.getInstance().getApi().getMovies(params.startPosition,PER_PAGE)
//加入到队列里
.enqueue(new Callback<Movies>() {
@Override
public void onResponse(Call<Movies> call, Response<Movies> response) {
if (response.body()!=null){
//把数据传递给PagedList
callback.onResult(response.body().getMovieList());
Log.d("ning","loadRange:"+response.body().getMovieList());
}
}
@Override
public void onFailure(Call<Movies> call, Throwable t) {
}
});
}
//获取我们的数据 网络请求 或者 数据库
}
5.MovieDataSourceFactory
package com.tiger.paging.paging;
import androidx.annotation.NonNull;
import androidx.paging.DataSource;
import com.tiger.paging.model.Movie;
public class MovieDataSourceFactory extends DataSource.Factory<Integer, Movie> {
@NonNull
@Override
public DataSource<Integer, Movie> create() {
return new MovieDataSource();
}
}
6. PageListAdapter
package com.tiger.paging.paging;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.paging.PagedListAdapter;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import com.tiger.paging.R;
import com.tiger.paging.model.Movie;
/**
* @author ningchuanqi
* @version V1.0
*/
public class MoviePagedListAdapter extends PagedListAdapter<Movie, MoviePagedListAdapter.MovieViewHolder> {
private Context context;
//差分,只更新需要更新的元素,而不是整个刷新数据源
private static final DiffUtil.ItemCallback<Movie> DIFF_CALLBACK = new DiffUtil.ItemCallback<Movie>() {
@Override
public boolean areItemsTheSame(@NonNull Movie oldItem, @NonNull Movie newItem) {
return oldItem == newItem;
}
@Override
public boolean areContentsTheSame(@NonNull Movie oldItem, @NonNull Movie newItem) {
return oldItem.equals(newItem);
}
};
public MoviePagedListAdapter(Context context) {
super(DIFF_CALLBACK);
this.context = context;
}
@NonNull
@Override
public MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View root = LayoutInflater.from(context).inflate(R.layout.item, parent, false);
return new MovieViewHolder(root);
}
@Override
public void onBindViewHolder(@NonNull MovieViewHolder holder, int position) {
Movie movie = getItem(position);
if(movie != null){
Picasso.get()
.load(movie.cover)
.placeholder(R.drawable.ic_launcher_foreground)
.error(R.drawable.ic_launcher_foreground)
.into(holder.imageView);
if(movie.title.length() >= 8){
movie.title = movie.title.substring(0,7);
}
holder.textViewTitle.setText(movie.title);
holder.textViewRate.setText(movie.rate);
}
}
class MovieViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private TextView textViewTitle;
private TextView textViewRate;
public MovieViewHolder(@NonNull View itemView) {
super(itemView);
this.imageView = itemView.findViewById(R.id.imageView);
this.textViewTitle = itemView.findViewById(R.id.textViewTitle);
this.textViewRate = itemView.findViewById(R.id.textViewRate);
}
}
}
7.ViewModel
package com.tiger.paging.paging;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.paging.LivePagedListBuilder;
import androidx.paging.PagedList;
import com.tiger.paging.model.Movie;
public class MovieViewModel extends ViewModel {
public LiveData<PagedList<Movie>> moviePagedList;
public MovieViewModel(){
//创建PageList对象 PageSize 预加载选项 等作用
PagedList.Config config = new PagedList.Config.Builder()
//设置控件占位
.setEnablePlaceholders(false)
//设置固定页容量
.setPageSize(MovieDataSource.PER_PAGE)
//设置当距离底部还有多少条数据时开始加载下一页 与页面高度有关
.setPrefetchDistance(1)
//设置首次加载的数量
.setInitialLoadSizeHint(MovieDataSource.PER_PAGE)
.setMaxSize(65536 * MovieDataSource.PER_PAGE)
.build();
moviePagedList = new LivePagedListBuilder<>(
new MovieDataSourceFactory(),config
)
.build();
}
}
8.Activity
package com.tiger.paging;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.paging.PagedList;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import com.tiger.paging.model.Movie;
import com.tiger.paging.paging.MoviePagedListAdapter;
import com.tiger.paging.paging.MovieViewModel;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
//垂直布局
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//
MoviePagedListAdapter adapter = new MoviePagedListAdapter(this);
recyclerView.setAdapter(adapter);
//pageList 和 MovieDataSource 是在这里初始化的
MovieViewModel movieViewModel = new ViewModelProvider(this).get(MovieViewModel.class);
movieViewModel.moviePagedList.observe(this, new Observer<PagedList<Movie>>() {
@Override
public void onChanged(PagedList<Movie> movies) {
//设置要显示的新列表。如果已显示列表,则将在后台线程上计算差异,该线程将在主线程上调度 Adapter.notifyItem 事件。更新UI
adapter.submitList(movies);
}
});
}
}