ImageSlider trong RecyclerView

Trong bài viết vừa rồi, tôi đã hướng dẫn các bạn dựng một ImageSlider trong ứng dụng Android. Thực chất, nó chỉ là một FrameLayout chứa một ViewPager với mỗi trang hiển thị một ảnh từ một ImageView, và một LinearLayout đóng vai trò là chỉ báo vị trí hiện tại của ViewPager. Và bài viết này sẽ giúp các bạn “nhét” ImageSlider này vào RecyclerView, cụ thể hơn là vị trí số 0, thích hợp cho các ứng dụng tin tức.

1. Tạo ImageSlider:

Trong bài viết trước, chúng ta đã gián tiếp tạo một FrameLayout chứa ViewPager và LinearLayout và cấu hình chúng lần lượt qua các bước. Như các bạn đã thấy, phần FrameLayout ngoài việc chứa hai View con thì nó không có vai trò nào khác, và ViewPager cùng Adapter của nó không quá liên kết với LinearLayout. Lần này, chúng ta “chơi trội” luôn bằng cách tạo một ImageSlider class duy nhất extends từ chính FrameLayout, và định nghĩa các hàm cấu hình ViewPager và LinearLayout trực tiếp trong nó.

Ở đây, tôi xin đưa ra code một lần với chú thích. Nếu bạn cảm thấy chưa hiểu lắm, xin mời đọc lại bài trước để hiểu tác dụng của từng hàm một.

2. Tạo RecyclerView với multiple item view types:

Dĩ nhiên, bạn không cần dùng cách nào khác ngoài việc tận dụng lợi thế mà RecyclerView đã cung cấp sẵn. Tất nhiên, nếu bạn thích dùng ListView thì bạn cũng có thể làm tương tự. Ở đây, chúng ta sẽ quan tâm tới class RecyclerViewAdapter vì 90% các công việc ở MainActivity đều là do nó đảm nhận. Tôi sẽ “nhét” nó vào trong class MainActivity luôn. Máu lửa hơn, tôi sẽ dùng trực tiếp RecyclerView làm contentView trong Java thay vì inflate từ XML:

Bây giờ, bạn cho chạy thử, kết quả rất tốt. Tuy nhiên, nếu bạn cuộn lên cuộn xuống tới khi phần tử đầu tiên, tức ImageSlider vượt ra khỏi màn hình, và khi quay trở lại, bạn tiếp tục “quẹt quẹt” kéo sang trái hoặc phải, bạn sẽ nhận thấy sẽ có hiện tượng bị chồng, tức ImageSlider tiếp tục tạo thêm một cặp ViewPager và LinearLayout nữa. Do phần View này đã được recycled lại, và khi nó hiện ra, RecyclerViewAdapter sẽ gọi lại onBindViewHolder, và ImageSlider sẽ tiếp tục gọi loadImages. Để khắc phục lỗi này, bạn quay trở lại phần ImageSlider#loadImages và bỏ comment dòng if mà tôi đã thêm và comment ngay từ đầu, và cho chạy lại. Kết quả là BUG HAS BEEN FIXED!

Và tiếp theo, xin mời các bạn tiếp tục “chiên xào nấu, thêm nước tương, nước mắm, đường muối” vào phần code vừa rồi để tối ưu hóa các code để có thêm kinh nghiệm để xử lí các project tương tự về sau. Chúc các bạn vui vẻ và thành công.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.