Kotlin玩Android第04篇 有效使用BaseAdapter 和 ViewHolder
本文章我們將去新建一個繼承BaseAdapter的Adapter類別,
讓我們可以創造更不一樣的Listview的item內容並且能了解到ArrayAdapter到底默默為我們實做了哪些內容。
建議搭配影片服用。
http://ohmerhe.com/2016/08/02/kotlin_one_method_no_viewholder/
當使用listview,並且想要在runtime時期新增一個item。
有可能會出現這類錯誤。
Android, ListView IllegalStateException: “The content of the adapter has changed but ListView did not receive a notification”
https://stackoverflow.com/questions/3132021/android-listview-illegalstateexception-the-content-of-the-adapter-has-
讓我們可以創造更不一樣的Listview的item內容並且能了解到ArrayAdapter到底默默為我們實做了哪些內容。
建議搭配影片服用。
聲明:
此篇文章主要是我觀看Lets Build That App的影片來後實作驗證的心得,然後記錄其中的不足之處(Ex: Android官方API文件等等),文章最後有附上參考資料來源(有興趣可以當作延伸閱讀)。BaseAdapter(用來定義專屬的Adapter)
這個類別是一個抽象類別,所以必須撰寫一個新類別去繼承它,
並且必須override 裡面的4個方法。
fun getView(postion: Int, convertView: View?, viewGroup: ViewGroup?): View
參數
position:指定回傳值view是回傳第幾行的view,例如0就代表是回傳的view是對應第0行的view。
converView: 曾經轉換過的view結果,需要判斷是否為空值。
viewGroup: view群組,可以間接取得呼叫getView的content,
例如: viewGroup!!.context
回傳
某一行的view(可以從參數position得知是哪一行)。
position:指定回傳值view是回傳第幾行的view,例如0就代表是回傳的view是對應第0行的view。
converView: 曾經轉換過的view結果,需要判斷是否為空值。
viewGroup: view群組,可以間接取得呼叫getView的content,
例如: viewGroup!!.context
回傳
某一行的view(可以從參數position得知是哪一行)。
fun getItem(p0: Int): Any
參數
p0:取得第p0行的值
回傳
第p0的值,可能是字串或整數等等...依據你的資料來源而定。
p0:取得第p0行的值
回傳
第p0的值,可能是字串或整數等等...依據你的資料來源而定。
fun getItemId(p0: Int): Long
回傳 第p0行的ID
fun getCount(): Int
回傳 資料來源有幾筆資料
這個回傳值的大小會影響到顯示item的筆數,
通常這樣用:return array.size
參考官方說明:
而如果使用ViewHolder的話,就像你身為一個台灣好老闆知道你們餐廳最多一次服務五個人,送完餐的服務生只要等待下次送餐就好,根本不用一直聘請和裁員只為了服務下位客人,你的餐廳至少穩定經營。
而建立一個ViewHolder可能就只要底下這樣一行
參考資料(文字):
BaseAdapter——convertView回收機制與動態控制項響這個回傳值的大小會影響到顯示item的筆數,
通常這樣用:return array.size
ViewHolder (ListView視圖的守護者)
Your code might call
findViewById()
frequently during the scrolling of ListView
, which can slow down performance. Even when the Adapter
returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById()
is to use the "view holder" design pattern.
小古翻譯:
當你在捲動ListView時如果一直呼叫findViewById()將會導致效能低落。即使你的Adapter返回inflated view有回收(我想這裡指的recycling,指得是使用convertView的回收再利用),但你依舊需要在convertView中使用findViewById()去查找元素並更新他們。
有一種重複利用的方式是名為 view holder的設計模式。
說明:
說明:
簡單講就是view holder能幫助你的App在更新ListView(譬如說你滑動你的ListView畫面,這也是一種更新喔!)時,盡可能同個位置的view只呼叫一次findViewById(),之後就是都用之前呼叫findViewById產生的view物件來更新,但如果沒有配合RecyclerView依然會。
比喻:
如果把ListView比喻成高檔餐廳, 則每個view都是一個服務生,然後每個view所持有的值都是餐點,然後每次LIstView只能顯示5個View則代表餐廳一次只有五個餐桌,最多同時只有5個服務生服務。
的服務生,明明服務生叫五個了很夠用,但你身為錢多老闆就是每次上新餐點就是要用新的服務生,無節操的一直在招募新的員工,後台則塞滿了一堆舊服務生(來不及辭退XD),即使你能很快將他們辭退避免浪費?!(回收記憶體)但你依然要花費大量時間在聘請人才(浪費CPU時間)。
而如果使用ViewHolder的話,就像你身為一個台灣好老闆知道你們餐廳最多一次服務五個人,送完餐的服務生只要等待下次送餐就好,根本不用一直聘請和裁員只為了服務下位客人,你的餐廳至少穩定經營。
如何利用View Holder:
private class ViewHolder(val nameTextView: TextView, val postionTextView: TextView)
參考資料(文字):
http://ohmerhe.com/2016/08/02/kotlin_one_method_no_viewholder/
參考資料(影片):
當使用listview,並且想要在runtime時期新增一個item。
有可能會出現這類錯誤。
Android, ListView IllegalStateException: “The content of the adapter has changed but ListView did not receive a notification”
https://stackoverflow.com/questions/3132021/android-listview-illegalstateexception-the-content-of-the-adapter-has-
留言
張貼留言