0

Android Architecture Components: Paging Library Phần 2

Bài trước mình đã giới thiệu qua về Paging Library ( 1 component của Android Architecture Components) và áp dụng nó trong load dữ liệu từ Local. Hôm nay, mình sẽ tiếp tục giới thiệu với mọi người cách áp dụng Library Paging với Rest API.

1. Thêm component vào project

Android Architecture Component có sẵn trong Google’s Maven repository. Để sử dụng cần thực hiện các bước sau: Open file build.grale trong project thêm dòng dưới:

allprojects {
repositories {
    jcenter()
    maven { url 'https://maven.google.com' }
}

}

Add Architecture Components

Trong bài này mình sẽ sử dụng LiveDataViewModel Open build.gradle trong module project thêm các dependencies:

ext {
retrofitVersion = "2.2.0"

} dependencies { .... implementation 'com.android.support:appcompat-v7:26.1.0'

//For Lifecycles, LiveData, and ViewModel
implementation 'android.arch.lifecycle:runtime:1.0.0'
implementation 'android.arch.lifecycle:extensions:1.0.0-alpha9-1'
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha9-1"
 
//For Paging
implementation 'android.arch.paging:runtime:1.0.0-alpha1'

//retrofit
compile "com.squareup.retrofit2:retrofit:${retrofitVersion}"
compile "com.squareup.retrofit2:converter-gson:${retrofitVersion}" 

}

2. Setting up Retrofit for Pagination

Trong code sample, chúng ta sẽ sử làm việc với API bằng cách sử dụng thư viện: Retrofit và GSON. Chúng ta sẽ làm việc với GitHub API với các GitHub User endpoint

public interface GitHubService {
@GET("/users")
Call<List<User>> getUser(@Query("since") int since, @Query("per_page") int perPage);

} Tạo file RetrofitService.class

public class GitHubApi {

public static GitHubService createGitHubService() {
    Retrofit.Builder builder = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("https://api.github.com");

    return builder.build().create(GitHubService.class);
}

}

3. Create TiledDataSource

Sử dụng TiledDataSource class để xác định một nguồn dữ liệu. Nó sử dụng để load data gia tăng, được sử dụng trong paging danh sách. Bạn có thể tải các trang tùy ý dựa trên thông tin vị trí và có thể cung cấp số lượng cố định mỗi lần load dữ liệu. TiledDataSource hỗ trợ query các trang ở các vị trí tùy ý, vì vậy có thể cung cấp dữ liệu cho PagedLists theo thứ tự tùy ý. Tạo class kế thừ TiledDataSource

public class TDataSource extends TiledDataSource<User> {
GitHubService gitHubService;

public TDataSource() {
    gitHubService = GitHubApi.createGitHubService();
}

//Number of items that this DataSource can provide in total.
@Override
public int countItems() {
    return DataSource.COUNT_UNDEFINED;
}

//Called to load items at from the specified position range.
@Override
public List<User> loadRange(int startPosition, int count) {
    List<User> gitHubUser = new ArrayList();
    try {
        Response<List<User>> response = gitHubService.getUser(startPosition, count).execute();
        if (response.isSuccessful() && response.code() == 200) {
            gitHubUser.addAll(response.body());
        } else {
            Log.e("API CALL", response.message());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return gitHubUser;
}

}

4. Create ViewModel

Trong ViewModel, chúng ta sẽ kế thừa từ Architecture Component ViewModel, và làm việc với LiveData of PagedList

public class UserViewModel extends ViewModel {

public LiveData<PagedList<User>> userList;
TDataSource tDataSource;

public UserViewModel() {

}

public void init(UserDao userDao) {

    userList = new LivePagedListProvider<Integer, User>() {
        @Override
        protected DataSource<Integer, User> createDataSource() {
            tDataSource = new TDataSource();
            return tDataSource;
        }

    }.create(0, new PagedList.Config.Builder()
            .setEnablePlaceholders(false)
            .setPageSize(20)
            .setInitialLoadSizeHint(20)
            .build());
}

}

LivePagedListProvider: Nó được sử dụng để khởi tạo Database trả về LiveData PagingList: PagedList là một List mà load data trong các trang từ DataSource.Tất cả data trong một PagedList được load từ DataSource của nó. Tạo một PagedList tải dữ liệu từ DataSource ngay lập tức, và vì lý do này, be done on a background thread. Các PagedList xây dựng sau đó có thể được chuyển đến và sử dụng trên thread UI. Điều này được thực hiện để ngăn chặn việc chuyển một danh sách không có nội dung tải đến chủ đề giao diện người dùng, mà thường không được trình bày cho người dùng.

5. Create Adapter

Để nói với PagedListAdapter làm thế nào để phân biệt sự khác biệt giữa hai item, bạn sẽ cần phải implement new class, DiffCallback. Ở đây, bạn sẽ xác định hai điều.

public class User {
public static DiffCallback<User> DIFF_CALLBACK = new DiffCallback<User>() {
    @Override
    public boolean areItemsTheSame(@NonNull User oldItem, @NonNull User newItem) {
        return oldItem.userId == newItem.userId;
    }

    @Override
    public boolean areContentsTheSame(@NonNull User oldItem, @NonNull User newItem) {
        return oldItem.equals(newItem);
    }
};

@Override public boolean equals(Object obj) { if (obj == this) return true;

    User user = (User) obj;

    return user.userId == this.userId && user.firstName == this.firstName;
}
....

}

Create Adapter

public class UserAdapter extends PagedListAdapter<User, UserAdapter.UserItemViewHolder> {


protected UserAdapter() {
    super(User.DIFF_CALLBACK);
}

@Override
public UserItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
    View view = layoutInflater.inflate(R.layout.item_user_list, parent, false);
    return new UserItemViewHolder(view);
}

@Override
public void onBindViewHolder(UserItemViewHolder holder, int position) {
    User user= getItem(position);
    if(user!=null) {
        holder.bindTo(user);
    }
}

static class UserItemViewHolder extends RecyclerView.ViewHolder {
    TextView userName, userId;

    public UserItemViewHolder(View itemView) {
        super(itemView);
        userId = itemView.findViewById(R.id.userId);
        userName = itemView.findViewById(R.id.userName);
    }

    public void bindTo(User user) {
        userName.setText(user.firstName);
        userId.setText(String.valueOf(user.userId));
    }
}

}

6. Create RecyclerView

LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(llm);
 
 UserViewModel viewModel = ViewModelProviders.of(this).get(UserViewModel.class);
 viewModel.init(userDao);
 final UserAdapter userUserAdapter = new UserAdapter();
 
 viewModel.userList.observe(this, pagedList -> {
        userUserAdapter.setList(pagedList);
 });
 
 recyclerView.setAdapter(userUserAdapter);

Dowload project


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí