Giới thiệu
MergeAdapter
là một class có sẵn trong recyclerview:1.2.0-alpha02
cho phép bạn kết hợp tuần tự nhiều adapter để hiển thị trong một RecyclerView
. Điều này cho phép bạn đóng gói các adapter một cách tốt hơn thay vì phải kết hợp nhiều nguồn data vào trong một adapter (sử dụng nhiều kiểu ViewHolder
), giữ chúng thống nhất và có khả năng sử dụng lại.
MergeAdapter
cho phép hiển thị nội dung của nhiều adapter trong một sequence. Ví dụ, ta có 3 adapter như sau:
1 2 3 4 5 6 7 8 | val firstAdapter<span class="token punctuation">:</span> FirstAdapter <span class="token operator">=</span> … val secondAdapter<span class="token punctuation">:</span> SecondAdapter <span class="token operator">=</span> … val thirdAdapter<span class="token punctuation">:</span> ThirdAdapter <span class="token operator">=</span> … val mergeAdapter <span class="token operator">=</span> <span class="token function">MergeAdapter</span><span class="token punctuation">(</span>firstAdapter<span class="token punctuation">,</span> secondAdapter<span class="token punctuation">,</span> thirdAdapter<span class="token punctuation">)</span> recyclerView<span class="token punctuation">.</span>adapter <span class="token operator">=</span> mergeAdapter |
recyclerView
sẽ hiển thị các item của mỗi adapter một cách tuần tự.
Sử dụng các adapter khác nhau cho phép ta phân tách tốt hơn các mối liên kết của từng phần liên tiếp trong một danh sách (list
). Ví dụ, nếu ta muốn hiển thị một title
, ta không cần phải viết logic để xử lý việc ẩn/hiện tiêu đề cho cùng một item trong một adapter. Thay vào đó ta có thể khai báo riêng một adapter chứa các item hiển thị title
.
Ví dụ
Ta tạo một màn hình hiển thị 1 danh sách cơ bản với các đối tượng Fruit
, Flower
và Animal
với các thuộc tính đơn giản như sau:
1 2 3 4 5 | data <span class="token keyword">class</span> <span class="token class-name">Fruit</span><span class="token punctuation">(</span> <span class="token keyword">var</span> id<span class="token punctuation">:</span> Int<span class="token punctuation">,</span> <span class="token keyword">var</span> name<span class="token punctuation">:</span> String <span class="token punctuation">)</span> |
1 2 3 4 5 | data <span class="token keyword">class</span> <span class="token class-name">Flower</span><span class="token punctuation">(</span> <span class="token keyword">var</span> id<span class="token punctuation">:</span> Int<span class="token punctuation">,</span> <span class="token keyword">var</span> name<span class="token punctuation">:</span> String <span class="token punctuation">)</span> |
1 2 3 4 5 | data <span class="token keyword">class</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span> <span class="token keyword">var</span> id<span class="token punctuation">:</span> Int<span class="token punctuation">,</span> <span class="token keyword">var</span> name<span class="token punctuation">:</span> String <span class="token punctuation">)</span> |
Tương ứng với mỗi đối tượng là một adapter. Ta sẽ triển khai 3 adapter như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <span class="token keyword">class</span> <span class="token class-name">FruitAdapter</span><span class="token punctuation">(</span><span class="token keyword">private</span> val FruitList<span class="token punctuation">:</span> List<span class="token operator"><</span>Fruit<span class="token operator">></span><span class="token punctuation">)</span> <span class="token punctuation">:</span> RecyclerView<span class="token punctuation">.</span>Adapter<span class="token operator"><</span>FruitViewHolder<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> override fun <span class="token function">onCreateViewHolder</span><span class="token punctuation">(</span><span class="token keyword">parent</span><span class="token punctuation">:</span> ViewGroup<span class="token punctuation">,</span> viewType<span class="token punctuation">:</span> Int<span class="token punctuation">)</span><span class="token punctuation">:</span> FruitViewHolder <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">FruitViewHolder</span><span class="token punctuation">(</span> LayoutInflater<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">parent</span><span class="token punctuation">.</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">inflate</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>layout<span class="token punctuation">.</span>item_fruit<span class="token punctuation">,</span> <span class="token keyword">parent</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> override fun <span class="token function">getItemCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> Int <span class="token punctuation">{</span> <span class="token keyword">return</span> FruitList<span class="token punctuation">.</span>size <span class="token punctuation">}</span> override fun <span class="token function">onBindViewHolder</span><span class="token punctuation">(</span>holder<span class="token punctuation">:</span> FruitViewHolder<span class="token punctuation">,</span> position<span class="token punctuation">:</span> Int<span class="token punctuation">)</span> <span class="token punctuation">{</span> holder<span class="token punctuation">.</span>image<span class="token punctuation">.</span><span class="token function">setImageResource</span><span class="token punctuation">(</span>FruitList<span class="token punctuation">[</span>position<span class="token punctuation">]</span><span class="token punctuation">.</span>id<span class="token punctuation">)</span> holder<span class="token punctuation">.</span>textViewName<span class="token punctuation">.</span><span class="token function">setText</span><span class="token punctuation">(</span>FruitList<span class="token punctuation">[</span>position<span class="token punctuation">]</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">FruitViewHolder</span><span class="token punctuation">(</span>itemView<span class="token punctuation">:</span> View<span class="token punctuation">)</span> <span class="token punctuation">:</span> RecyclerView<span class="token punctuation">.</span><span class="token function">ViewHolder</span><span class="token punctuation">(</span>itemView<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> image <span class="token operator">=</span> itemView<span class="token punctuation">.</span>findViewById<span class="token operator"><</span>ImageView<span class="token operator">></span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>image<span class="token punctuation">)</span> <span class="token keyword">var</span> textViewName <span class="token operator">=</span> itemView<span class="token punctuation">.</span>findViewById<span class="token operator"><</span>TextView<span class="token operator">></span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>textViewName<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <span class="token keyword">class</span> <span class="token class-name">FlowerAdapter</span><span class="token punctuation">(</span><span class="token keyword">private</span> val FlowerList<span class="token punctuation">:</span> List<span class="token operator"><</span>Flower<span class="token operator">></span><span class="token punctuation">)</span> <span class="token punctuation">:</span> RecyclerView<span class="token punctuation">.</span>Adapter<span class="token operator"><</span>FlowerViewHolder<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> override fun <span class="token function">onCreateViewHolder</span><span class="token punctuation">(</span><span class="token keyword">parent</span><span class="token punctuation">:</span> ViewGroup<span class="token punctuation">,</span> viewType<span class="token punctuation">:</span> Int<span class="token punctuation">)</span><span class="token punctuation">:</span> FlowerViewHolder <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">FlowerViewHolder</span><span class="token punctuation">(</span> LayoutInflater<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">parent</span><span class="token punctuation">.</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">inflate</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>layout<span class="token punctuation">.</span>item_flower<span class="token punctuation">,</span> <span class="token keyword">parent</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> override fun <span class="token function">getItemCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> Int <span class="token punctuation">{</span> <span class="token keyword">return</span> FlowerList<span class="token punctuation">.</span>size <span class="token punctuation">}</span> override fun <span class="token function">onBindViewHolder</span><span class="token punctuation">(</span>holder<span class="token punctuation">:</span> FlowerViewHolder<span class="token punctuation">,</span> position<span class="token punctuation">:</span> Int<span class="token punctuation">)</span> <span class="token punctuation">{</span> holder<span class="token punctuation">.</span>image<span class="token punctuation">.</span><span class="token function">setImageResource</span><span class="token punctuation">(</span>FlowerList<span class="token punctuation">[</span>position<span class="token punctuation">]</span><span class="token punctuation">.</span>id<span class="token punctuation">)</span> holder<span class="token punctuation">.</span>textViewName<span class="token punctuation">.</span><span class="token function">setText</span><span class="token punctuation">(</span>FlowerList<span class="token punctuation">[</span>position<span class="token punctuation">]</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">FlowerViewHolder</span><span class="token punctuation">(</span>itemView<span class="token punctuation">:</span> View<span class="token punctuation">)</span> <span class="token punctuation">:</span> RecyclerView<span class="token punctuation">.</span><span class="token function">ViewHolder</span><span class="token punctuation">(</span>itemView<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> image <span class="token operator">=</span> itemView<span class="token punctuation">.</span>findViewById<span class="token operator"><</span>ImageView<span class="token operator">></span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>image<span class="token punctuation">)</span> <span class="token keyword">var</span> textViewName <span class="token operator">=</span> itemView<span class="token punctuation">.</span>findViewById<span class="token operator"><</span>TextView<span class="token operator">></span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>textViewName<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <span class="token keyword">class</span> <span class="token class-name">AnimalAdapter</span><span class="token punctuation">(</span><span class="token keyword">private</span> val animalList<span class="token punctuation">:</span> List<span class="token operator"><</span>Animal<span class="token operator">></span><span class="token punctuation">)</span> <span class="token punctuation">:</span> RecyclerView<span class="token punctuation">.</span>Adapter<span class="token operator"><</span>AnimalViewHolder<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> override fun <span class="token function">onCreateViewHolder</span><span class="token punctuation">(</span><span class="token keyword">parent</span><span class="token punctuation">:</span> ViewGroup<span class="token punctuation">,</span> viewType<span class="token punctuation">:</span> Int<span class="token punctuation">)</span><span class="token punctuation">:</span> AnimalViewHolder <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">AnimalViewHolder</span><span class="token punctuation">(</span> LayoutInflater<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">parent</span><span class="token punctuation">.</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">inflate</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>layout<span class="token punctuation">.</span>item_animal<span class="token punctuation">,</span> <span class="token keyword">parent</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> override fun <span class="token function">getItemCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> Int <span class="token punctuation">{</span> <span class="token keyword">return</span> animalList<span class="token punctuation">.</span>size <span class="token punctuation">}</span> override fun <span class="token function">onBindViewHolder</span><span class="token punctuation">(</span>holder<span class="token punctuation">:</span> AnimalViewHolder<span class="token punctuation">,</span> position<span class="token punctuation">:</span> Int<span class="token punctuation">)</span> <span class="token punctuation">{</span> holder<span class="token punctuation">.</span>image<span class="token punctuation">.</span><span class="token function">setImageResource</span><span class="token punctuation">(</span>animalList<span class="token punctuation">[</span>position<span class="token punctuation">]</span><span class="token punctuation">.</span>id<span class="token punctuation">)</span> holder<span class="token punctuation">.</span>textViewName<span class="token punctuation">.</span><span class="token function">setText</span><span class="token punctuation">(</span>animalList<span class="token punctuation">[</span>position<span class="token punctuation">]</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">AnimalViewHolder</span><span class="token punctuation">(</span>itemView<span class="token punctuation">:</span> View<span class="token punctuation">)</span> <span class="token punctuation">:</span> RecyclerView<span class="token punctuation">.</span><span class="token function">ViewHolder</span><span class="token punctuation">(</span>itemView<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> image <span class="token operator">=</span> itemView<span class="token punctuation">.</span>findViewById<span class="token operator"><</span>ImageView<span class="token operator">></span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>image<span class="token punctuation">)</span> <span class="token keyword">var</span> textViewName <span class="token operator">=</span> itemView<span class="token punctuation">.</span>findViewById<span class="token operator"><</span>TextView<span class="token operator">></span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>textViewName<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Sử dụng với MergeAdapter
ta được kết quả như sau: