12/08/2018, 17:10

Recyclerview sử dụng sao cho hiệu quả

RecyclerView là một wedget được sử dụng rất phổ biến để hiện thị một danh sách trong các ứng dụng android. Nó là một phiên bản nâng cấp của ListView giúp cho việc quản lý và hiển thị danh sách dữ liệu một cách hiệu quả và đơn giản . Việc sử dụng RecyclerView không quá khó đối với các lập trinh ...

RecyclerView là một wedget được sử dụng rất phổ biến để hiện thị một danh sách trong các ứng dụng android. Nó là một phiên bản nâng cấp của ListView giúp cho việc quản lý và hiển thị danh sách dữ liệu một cách hiệu quả và đơn giản . Việc sử dụng RecyclerView không quá khó đối với các lập trinh viên, nó rất dễ để có thể cài đặt, tuy nhiên không phải là không có những sai lầm khi cài đặt một RecyclerView làm cho hiệu năng của ứng dụng và trải nghiệm người dùng bị giảm xuống. Trong bài viết này sẽ điểm qua một số thao tác sử dụng RecyclerView sao cho hiệu quả.

Sử dụng recyclerView.setHasFixedSize(true) khi kích thước của các item trong RecyclerView không thay đổi khi thay đổi nội dung

Khi sử dụng thuộc tính này mỗi khi dữ liệu được cập nhật trong item của RecyclerView thì nó sẽ không requestLayout mà chỉ gọi invalidate để cập nhật lại nội dung bên trong item . Chúng ta có thể thấy được lợi ích của việc này từ View lifecycle bên dưới.

Chúng ta có thể thấy việc sử dụng invalidate hiệu quả hơn rất nhiều

Sử lý Item click listenner trong onCreateViewHolder(…)

Khi xử lý sự kiện người dùng click vào một item trong RecyclerView chúng ta nên xử lý bên trong onCreateViewHolder(…) và luôn sử dụng getAdapterPosition() để có thể lấy được chính xác index của item vì item có thể di chuyển trong adapter mà nó không đồng nhất với layout position.

    private OnItemClickListener mOnItemClickListener;
    ....
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = ....
        final RecyclerView.ViewHolder viewHolder = new ViewHolder(view);
        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int pos = viewHolder.getAdapterPosition();
                if (mOnItemClickListener != null && pos != RecyclerView.NO_POSITION) {
                    mOnItemClickListener.onClick(pos);
                }
            }
        });

        return viewHolder;
    }

Sử dụng layout ids như là các view type khi RecyclerView có nhiều loại item khác nhau

Khi trong danh sách có nhiều loại item khác nhau chúng ta thường tạo thêm những biến constant để đại diện cho những view type khác nhau như đoạn code dưới đây:

    private static final int VIEW_TYPE1 = 1;
    private static final int VIEW_TYPE2 = 2;
    .....
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        /*bad*/
        View view;
        switch (viewType) {
            case VIEW_TYPE1:
                view = LayoutInflater.from(mContext).inflate(R.layout.item1, parent, false);
                break;
            case VIEW_TYPE2:
                view = LayoutInflater.from(mContext).inflate(R.layout.item2, parent, false);
                break;
        }
        return ViewHolder(view);
    }

Thay vì sử dụng như trên chúng ta có thể dùng layout id là những view type của item

    @Override
    public int getItemViewType(int position) {
        return mData.size() > 0 && position == mData.size() - 1 ? R.layout.item1 : R.layout.item2;
    }
    ...
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(viewType, parent, false);
        return new ViewHolder1(view);
    }

Sử dụng DiffUtil để thêm dữ liệu vào RecyclerView

Thông thuường khi muốn hiển thị dữ liệu mới khi dữ liệu trong RecyclerView thay đổi chúng ta sử dụng notifyDataSetChanged() để cập nhật UI. Có một cách hay hơn giúp cải thiện performance đó là sử dụng DiffUtil. Để sử dụng DiffUtil bạn cần phải implement DiffUtil.Callback và cài đặt các hàm logic bên dưới để nó có thể hoạt động

Sử dụng ItemDecoration

Trong một danh sách đôi khi chúng ta muốn ngăn cách chúng bằng một đường kẻ hoặc một khoảng trắng, chúng ta có thể thực hiện nó bằng cách thêm các thành phần này vào layout của item. Tuy nhiên bạn nên sử dụng ItemDecoration để thực hiện việc này

mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
             mLayoutManager.getOrientation());
     recyclerView.addItemDecoration(mDividerItemDecoration);

Bạn hoàn toàn có thể custom một ItemDecoration theo ý mình bằng việc extends RecyclerView.ItemDecoration class.

Thảm khảo: https://medium.com/@iammert/using-diffutil-in-android-recyclerview-bdca8e4fbb00

0