mình cũng gặp vấn đề với viewholder. sau một hồi tìm hiểu, cảm thấy cũng thấy có vẻ hiểu hơn về vấn đề này nên muốn chia sẻ thêm cho mọi người.
đầu tiên xem xét một custom adapter không có view holder
Mã nguồn PHP:
[color=#000000]
[/color][color=#007700]public [/color][color=#0000bb]view getview[/color][color=#007700]([/color][color=#0000bb]int position[/color][color=#007700], [/color][color=#0000bb]view convertview[/color][color=#007700], [/color][color=#0000bb]viewgroup parent[/color][color=#007700]) { [/color][color=#0000bb]layoutinflater inflater [/color][color=#007700]= ([/color][color=#0000bb]layoutinflater[/color][color=#007700]) [/color][color=#0000bb]context [/color][color=#007700].[/color][color=#0000bb]getsystemservice[/color][color=#007700]([/color][color=#0000bb]context[/color][color=#007700].[/color][color=#0000bb]layout_inflater_service[/color][color=#007700]); [/color][color=#0000bb]view rowview [/color][color=#007700]= [/color][color=#0000bb]inflater[/color][color=#007700].[/color][color=#0000bb]inflate[/color][color=#007700]([/color][color=#0000bb]r[/color][color=#007700].[/color][color=#0000bb]layout[/color][color=#007700].[/color][color=#0000bb]rowlayout[/color][color=#007700], [/color][color=#0000bb]parent[/color][color=#007700], [/color][color=#0000bb]false[/color][color=#007700]); [/color][color=#0000bb]textview textview [/color][color=#007700]= ([/color][color=#0000bb]textview[/color][color=#007700]) [/color][color=#0000bb]rowview[/color][color=#007700].[/color][color=#0000bb]findviewbyid[/color][color=#007700]([/color][color=#0000bb]r[/color][color=#007700].[/color][color=#0000bb]id[/color][color=#007700].[/color][color=#0000bb]label[/color][color=#007700]); [/color][color=#0000bb]imageview imageview [/color][color=#007700]= ([/color][color=#0000bb]imageview[/color][color=#007700]) [/color][color=#0000bb]rowview[/color][color=#007700].[/color][color=#0000bb]findviewbyid[/color][color=#007700]([/color][color=#0000bb]r[/color][color=#007700].[/color][color=#0000bb]id[/color][color=#007700].[/color][color=#0000bb]icon[/color][color=#007700]); [/color][color=#0000bb]textview[/color][color=#007700].[/color][color=#0000bb]settext[/color][color=#007700]([/color][color=#0000bb]values[/color][color=#007700][[/color][color=#0000bb]position[/color][color=#007700]]); [/color][color=#0000bb]imageview[/color][color=#007700].[/color][color=#0000bb]setimageresource[/color][color=#007700]([/color][color=#0000bb]r[/color][color=#007700].[/color][color=#0000bb]drawable[/color][color=#007700].[/color][color=#0000bb]img[/color][color=#007700]); return [/color][color=#0000bb]rowview[/color][color=#007700]; }[/color]
ta có thể thấy mỗi khi getview được gọi thì các công việc phải thực hiện như sau:
- inflate layout của list item - ở trên là rowview
- findviewbyid() để lấy các view thành phần của rowview cần set.
- set các view trên
- return rowview
bây giờ xem xét một custom adapter có view holder
Mã nguồn PHP:
[color=#000000]
[/color][color=#007700]public [/color][color=#0000bb]view getview[/color][color=#007700]([/color][color=#0000bb]int position[/color][color=#007700], [/color][color=#0000bb]view convertview[/color][color=#007700], [/color][color=#0000bb]viewgroup parent[/color][color=#007700]) { [/color][color=#0000bb]view rowview [/color][color=#007700]= [/color][color=#0000bb]convertview[/color][color=#007700]; [/color][color=#ff8000]// reuse views [/color][color=#007700]if ([/color][color=#0000bb]rowview [/color][color=#007700]== [/color][color=#0000bb]null[/color][color=#007700]) { [/color][color=#0000bb]layoutinflater inflater [/color][color=#007700]= [/color][color=#0000bb]context[/color][color=#007700].[/color][color=#0000bb]getlayoutinflater[/color][color=#007700](); [/color][color=#0000bb]rowview [/color][color=#007700]= [/color][color=#0000bb]inflater[/color][color=#007700].[/color][color=#0000bb]inflate[/color][color=#007700]([/color][color=#0000bb]r[/color][color=#007700].[/color][color=#0000bb]layout[/color][color=#007700].[/color][color=#0000bb]rowlayout[/color][color=#007700], [/color][color=#0000bb]null[/color][color=#007700]); [/color][color=#ff8000]// configure view holder [/color][color=#0000bb]viewholder viewholder [/color][color=#007700]= new [/color][color=#0000bb]viewholder[/color][color=#007700](); [/color][color=#0000bb]viewholder[/color][color=#007700].[/color][color=#0000bb]text [/color][color=#007700]= ([/color][color=#0000bb]textview[/color][color=#007700]) [/color][color=#0000bb]rowview[/color][color=#007700].[/color][color=#0000bb]findviewbyid[/color][color=#007700]([/color][color=#0000bb]r[/color][color=#007700].[/color][color=#0000bb]id[/color][color=#007700].[/color][color=#0000bb]textview01[/color][color=#007700]); [/color][color=#0000bb]viewholder[/color][color=#007700].[/color][color=#0000bb]image [/color][color=#007700]= ([/color][color=#0000bb]imageview[/color][color=#007700]) [/color][color=#0000bb]rowview [/color][color=#007700].[/color][color=#0000bb]findviewbyid[/color][color=#007700]([/color][color=#0000bb]r[/color][color=#007700].[/color][color=#0000bb]id[/color][color=#007700].[/color][color=#0000bb]imageview01[/color][color=#007700]); [/color][color=#0000bb]rowview[/color][color=#007700].[/color][color=#0000bb]settag[/color][color=#007700]([/color][color=#0000bb]viewholder[/color][color=#007700]); } [/color][color=#ff8000]// fill data [/color][color=#0000bb]viewholder holder [/color][color=#007700]= ([/color][color=#0000bb]viewholder[/color][color=#007700]) [/color][color=#0000bb]rowview[/color][color=#007700].[/color][color=#0000bb]gettag[/color][color=#007700](); [/color][color=#0000bb]string s [/color][color=#007700]= [/color][color=#0000bb]names[/color][color=#007700][[/color][color=#0000bb]position[/color][color=#007700]]; [/color][color=#0000bb]holder[/color][color=#007700].[/color][color=#0000bb]text[/color][color=#007700].[/color][color=#0000bb]settext[/color][color=#007700]([/color][color=#0000bb]s[/color][color=#007700]); [/color][color=#0000bb]holder[/color][color=#007700].[/color][color=#0000bb]image[/color][color=#007700].[/color][color=#0000bb]setimageresource[/color][color=#007700]([/color][color=#0000bb]r[/color][color=#007700].[/color][color=#0000bb]drawable[/color][color=#007700].[/color][color=#0000bb]ok[/color][color=#007700]); return [/color][color=#0000bb]rowview[/color][color=#007700]; }[/color]
ta có thể thấy sự khác biệt giữa 2 trường hợp này như sau:
- nếu convertview == null thì ta cần phải instance một object mới cho viewholder và thực hiện hai bước đầu tiên giống như trên, sau đó set tag cho viewholder. việc settag cho viewholder giống như bạn đánh một cái unique index cho view đó.
- trong trường hợp convertview != null thì chỉ việc get tag cho viewholder. từ đó ta có thể lấy được cái view thành phần mà không cần phải gọi lại các hàm findviewbyid.
- như gabk đã nói ở trên
mục đích của việc lưu giữ này là để thay đổi nội dung hiển thị của view mà tránh phải khởi tạo lại các thành phần.
ta có thể tránh được việc gọi liên tục hàm findviewbyid();
thực ra thì findviewbyid() cũng không tốn quá nhiều thời gian nếu app bạn nhỏ, nhưng vấn đề sẽ nghiêm trọng hơn nếu row layout mà bạn sử dụng khá phức tạp và số lượng row là lớn.
Trong hành trình yêu, có những điểm đến chẳng thể tìm thấy trên bất kỳ bản đồ nào. Đó là những miền đất của cảm xúc chỉ mở ra khi ta dám bước qua ranh giới của những lề thói, dám khám phá những cung...
Cỗ máy yêu thương – Giai điệu mới cho đôi lứa