Hỏi về hiệu suất Android
Có bác nào hiểu về hiệu suất khi làm ứng dụng Android không giúp em với ạ. Em có 1 cái RecyclerView, trong mỗi phần tử RecyclerView đó em có 1 chút text, và 1 RecyclerView nữa chứa list các ảnh. Có khi em còn làm RecyclerView mẹ có nhiều type (type chứa ảnh, type chứa text, type chứa link), trong item của RecyclerView mẹ đó cũng là 1 RecyclerView nữa. Vì nó là 1 đống các thứ như thế nên khi scroll nó lag lắm ạ (data đều load api hết nhé). Bác nào có giải pháp cho những RecyclerView phức tạp thế này hoặc có cách nào khác hay hơn không giúp em với ạ? Như Zalo chẳng hạn có 1 đống type: ghi âm, ảnh, text, video mà scroll vẫn mượt vù vù.. Mong các bác giúp đỡ em với ạ. Em cảm ơn.
2 ANSWERS
Case hay. Khi người dùng swipe phải (recyclerview chứa recyclerview horizontal, thì cha đứng lai, con sẽ sử dụng lại view để tạo => mượt). Khi swipe xuống (vertical), mỗi view bên trong inner recycler view dc inflated lại. Nguyên nhân: các nested view trong recylerview đều có view pool của nó. Sửa: Đặt recylerview chỉ là single view pool: public OuterRecyclerViewAdapter(List<Item> items) { viewPool = new RecyclerView.RecycledViewPool(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //tạo viewholder. holder.innerRecyclerView.setRecycledViewPool(....viewPool); } Cách làm này làm cho cha và con cùng một view pool, thế là mượt hơn. Hi vọng giúp dc bạn.
Bác có thể cho em xin mail / skype để được tư vấn free cụ thể hơn ko ạ?
Khi khởi tạo adapter, mình sẽ tạo luôn 1 viewPool bằng câu lệnh: viewPool = new RecyclerView.RecycledViewPool(); Sau đó, mình gán các nested view sử dụng chung các viewPool đó bằng cách: itemView.subRc.setRecycledViewPool(viewPool) phải ko bác?
Khởi tạo trong adapter (Y)
Em vừa test thấy ok đấy bác ạ. Nhưng em thử trường hợp nếu nested view của adapter cha mà lại là nhiều kiểu nested view khác nhau(2 trở lên). Thì khi scroll nested view, xong scroll mẹ sẽ bị lỗi cast data bác à. Hình như nó bảo là do nested view là 2 adapter khác nhau, mà mình đang tái sử dụng cái viewPool đó nên nó bị lỗi ko thể lấy viewPool của adapter này gán cho viewPool của adapter kia. Bác có giải pháp gì ko nếu mà nó như thế ạ @@
Bạn thực hiện loadmore chứ đừng load hết một lần thì ứng dụng sẽ nhẹ nhàng hơn, giảm tải hơn.
Nhưng làm kiểu load more, ví dụ load 10 phần tử 1 đi. Khi người dùng scroll nhanh làm cái vèo 1 cái là đi xa tới hơn 10 item rồi. Lúc ấy nó lại bị dừng và chờ tải dữ liệu 10 item tiếp theo lên chứ bạn @@
bạn có thể load 20 items 1 lúc, khi người dùng scroll tới items thứ 10 thì bạn lại load tiếp 20 items tiếp theo. Tuy nhiên để tối ưu code này mình nghĩ chỉ load more là chưa đủ. Bạn còn cần tối ưu media player trong các item nữa
mình nghĩ ko phải nhiều item mà là do item đang chứa nhiều view quá, còn cả khởi tạo adapter trong đó nữa nên nó mới thế. mình đã thử set adapter mẹ chỉ có 10item thôi mà vẫn lag mà (giật 1 phát khi scroll nhanh chứ ko phải cứ scroll là giật). Bạn có thể cho mình tham khảo một số cách tối ưu media player ko?
Thay vì nhét recycler view con vào viewholder của recycler view cha, bạn có mảng data con r thì thực hiện add vào view có sẵn xem (LinearLayout với orientation vertical). Trc mình làm thử, việc tạo adapter trong view holder con có làm view bị khựng lại mỗi khi scroll thật nhưng k hiểu rõ nguyên nhân. Add View bt thì mình thấy mượt hơn chút
@VoTheAnh nghĩa là giờ mình sẽ ko tạo adapter con bên trong, mà sẽ tạo view LinearLayout với chế độ xem orientation vertical để hiển thị phải ko bạn?
@tony yes, bạn truyền list data vào viewholder, có bn item thì add bấy nhiều view vào linear đó là đc
Note trước mỗi lần bind bạn phải removeAllView đi đã nhé, k lúc recycle nó bị lưu lại view của item trước đó
@tony Bạn có thể mô tả thêm cách bạn lấy dữ liệu và truyền dữ liệu cho RecyclerView được không?
Mình load api về đc data của cả RecyclerView mẹ và con. Data của mình có dạng DataAll gồm list Data, trong mỗi Data(của RecyclerView mẹ) có 1 list sub_data(của RecyclerView con). Trong BindHolder của RecyclerView mẹ mình bind data lên, và khởi tạo 1 RecyclerView con trong đó
Nếu có thể, bạn có thể làm như bạn @teamvietdev nói:
Làm giống facebook chẳng hạn.
Nhưng làm kiểu load more, ví dụ load 10 phần tử 1 đi. Khi người dùng scroll nhanh làm cái vèo 1 cái là đi xa tới hơn 10 item rồi. Lúc ấy nó lại bị dừng và chờ tải dữ liệu 10 item tiếp theo lên chứ bạn @@ Với cả mình cũng test rồi. 10 item mà RecyclerView có nhiều thứ bên trong như thế scroll nó cũng giật bạn à. Chỉ cần scroll nó ra ngoài item đang hiển thị trên màn hình thôi là nó bị delay rồi. Chưa đến 1s nhưng nó bị giật khựng lại cái.