Adapter實(shí)現(xiàn)ListView帶多選框等狀態(tài)的自定義控件的注意事項(xiàng)
我需要的ListView是如圖一樣的實(shí)現(xiàn)SD卡資源文件瀏覽列表,每個(gè)列表項(xiàng)由一個(gè)ImageView、TextView、CheckBox組成,并且要求當(dāng)整個(gè)列表中有一個(gè)或一個(gè)以上的Checkbox被選中時(shí),右上角的搜索按鈕就顯示出來,否則就隱藏,因此需要對每個(gè)列表項(xiàng)的CheckBox設(shè)置監(jiān)聽器。若使用Android提供的Adapter實(shí)現(xiàn)起來比較復(fù)雜,所以我選擇繼承BaseAdapter來實(shí)現(xiàn)自己的Adapter。
首先要知道的是ListView顯示原理。ListView接收了Adapter之后,ListView的列表項(xiàng)數(shù)據(jù)是來源于接收的Adapter的。當(dāng)ListView要展現(xiàn)出來的時(shí)候,ListView就會(huì)調(diào)用Adapter的getCount方法來獲得一共需要繪制多少個(gè)列表項(xiàng),之后就開始調(diào)用getView方法來獲得每個(gè)列表項(xiàng)的View進(jìn)行裝載。也就是說ListView的列表項(xiàng)就是每次調(diào)用getView返回的View,每次調(diào)用getView獲得的列表項(xiàng)View是什么樣子,我們看到的這個(gè)列表項(xiàng)就是什么樣子。
我繼承BaseAdapter來實(shí)現(xiàn)自己的Adapter,至少需要重寫基本的getView、getCount、getItem、getItemID四個(gè)方法。其中g(shù)etCount和getView的功能如上所述,所以我要想實(shí)現(xiàn)對每個(gè)列表項(xiàng)多選框按鈕的監(jiān)聽就需要在getView中返回View給ListView之前,對View中的多選框設(shè)置監(jiān)聽器。getView方法中帶三個(gè)參數(shù)public View getView(int position,View convertView,ViewGroup parent),一般都是將convertView最為返回的View。
在這里,需要插播說明一下Android系統(tǒng)對ListView的實(shí)現(xiàn)小細(xì)節(jié)。Android構(gòu)造ListView列表項(xiàng)的時(shí)候每次只會(huì)構(gòu)造足夠滿足屏幕顯示數(shù)量的列表項(xiàng),一般都是10個(gè)左右。當(dāng)ListView的列表項(xiàng)多于屏幕能夠顯示的列表項(xiàng)的時(shí)候,ListView就可以上下拉動(dòng),每次拉動(dòng)顯示后續(xù)列表項(xiàng)時(shí)就會(huì)再次調(diào)用getView方法來構(gòu)造后續(xù)列表項(xiàng)的View。如果ListView是首次顯示出來,那么getView的參數(shù)View convertView就是null空的;如果是拉動(dòng)ListView調(diào)用的getView,那么這時(shí)getView的參數(shù)convertView就不再是null,而是隨著拉動(dòng)剛剛被拉走隱藏掉的列表項(xiàng)的View。這么做的好處是可以節(jié)省資源。
基于這個(gè)細(xì)節(jié),如果重寫getView方法時(shí),要將參數(shù)convertView作為返回View,那么getView中就應(yīng)該判斷convertView是否為null。為空的話就需要使用Inflater構(gòu)造出來,不為空的話就可以直接使用了。我的需求中需要對多選框進(jìn)行監(jiān)聽,所以在返回convertView之前需要中convertView中獲取多選框控件并設(shè)置監(jiān)聽器。
一開始,我以為這樣就能夠?qū)崿F(xiàn)我的需求了,但是出來的結(jié)果卻意想不到。當(dāng)我點(diǎn)擊一個(gè)多選框后,將列表往下拉,下面出來的沒有選中的列表框也變成選中的狀態(tài)。注意到我每次點(diǎn)擊一個(gè)多選框后往下拉同步被選中的多選框的距離都是不變的,總是相隔11項(xiàng)。于是,回想getView中convertView參數(shù)的特點(diǎn),當(dāng)我往下拉的時(shí)候,ListView調(diào)用getView方法中的convertView就是回收來的因?yàn)槔瓌?dòng)被隱藏的View。在我這個(gè)例子中,由于多選框是一種帶有狀態(tài)標(biāo)示的控件,我的getView沒有對其狀態(tài)進(jìn)行重新設(shè)置,所以就造成了這種奇怪現(xiàn)象。我的解決方法是在我實(shí)現(xiàn)的Adapter類中創(chuàng)建一個(gè)boolean數(shù)組用于保存對應(yīng)列表項(xiàng)多選框的狀態(tài)(getView中第一個(gè)參數(shù)position就是列表項(xiàng)ID,是根據(jù)數(shù)據(jù)來標(biāo)識(shí),不是根據(jù)列表項(xiàng)View來標(biāo)識(shí)的,所以可以根據(jù)position來對列表項(xiàng)數(shù)據(jù)進(jìn)行選中和非選中標(biāo)識(shí)),每次調(diào)用getView都會(huì)在其中判斷position位置上的boolean值來決定多選框的狀態(tài)。
同樣的,基于這個(gè)原理,使用其它帶狀態(tài)的控件也需要注意getView回收的問題。當(dāng)然,也可以不使用convertView最為getView的返回結(jié)果,而在getView每次調(diào)用都重新構(gòu)造一個(gè)View,或者Adapter類中構(gòu)造一個(gè)與數(shù)據(jù)數(shù)量等長的View數(shù)組。不過這么做的話就比較消耗資源。
另外,BaseAdapter中的getItem和getItemId方法再構(gòu)造ListView構(gòu)造過程中并沒有使用過,不過據(jù)說是在關(guān)于ListView的一些監(jiān)聽器中會(huì)調(diào)用到,所以繼承BaseAdapter時(shí)最好也給這兩個(gè)方法返回一個(gè)有意義的值。getItemId一般返回對應(yīng)的position,getItem返回對應(yīng)position的列表數(shù)據(jù)對象。
- Android自定義Adapter的ListView的思路及代碼
- android開發(fā)中ListView與Adapter使用要點(diǎn)介紹
- ListView的Adapter使用 之 初學(xué)ArrayAdapter String
- ListView的Adapter使用(綁定數(shù)據(jù)) 之 自定義每一項(xiàng)的布局去綁定數(shù)據(jù)
- Android listview與adapter詳解及實(shí)例代碼
- Android開發(fā)中ListView自定義adapter的封裝
- 揭秘在ListView等AdapterView上動(dòng)態(tài)添加刪除項(xiàng)的陷阱
- ListView Adapter優(yōu)化 實(shí)例
- Android ListView適配器(Adapter)優(yōu)化方法詳解
- Android ListView自定義Adapter實(shí)現(xiàn)仿QQ界面
相關(guān)文章
Android中使用RecyclerView實(shí)現(xiàn)下拉刷新和上拉加載
RecyclerView 是Android L版本中新添加的一個(gè)用來取代ListView的SDK,它的靈活性與可替代性比listview更好。這篇文章主要介紹了Android中使用RecyclerView實(shí)現(xiàn)下拉刷新和上拉加載的相關(guān)資料,需要的朋友可以參考下2016-03-03
用Android Studio3.0新功能加快構(gòu)建速度
本文主要介紹了使用Android Studio3.0新功能,加快Android Studio的構(gòu)建速度等相關(guān)做法。2017-11-11
Android自定義view實(shí)現(xiàn)圓形進(jìn)度條效果
這篇文章主要介紹了Android自定義view實(shí)現(xiàn)圓形進(jìn)度條效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
淺談Android系統(tǒng)的基本體系結(jié)構(gòu)與內(nèi)存管理優(yōu)化
這篇文章主要介紹了Android系統(tǒng)的基本體系結(jié)構(gòu)與內(nèi)存管理優(yōu)化,非常簡潔明了地總結(jié)了系統(tǒng)服務(wù)及垃圾回收等安卓的一些主要特性,需要的朋友可以參考下2016-02-02
Android視頻加水印之FFmpeg的簡單應(yīng)用實(shí)例
最近有個(gè)需求,需要錄制視頻,能添加水印,所以下面這篇文章主要給大家介紹了關(guān)于Android視頻加水印之FFmpeg的簡單應(yīng)用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Kotlin 封裝萬能SharedPreferences存取任何類型詳解
這篇文章主要介紹了Kotlin 封裝萬能SharedPreferences存取任何類型詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05
詳解Android中fragment和viewpager的那點(diǎn)事兒
本文主要對Android中fragment和viewpager進(jìn)行詳細(xì)介紹,具有一定的參考價(jià)值,需要的朋友一起來看下吧2016-12-12
Android 實(shí)現(xiàn)ListView的點(diǎn)擊變色的實(shí)例
這篇文章主要介紹了Android 實(shí)現(xiàn)ListView的點(diǎn)擊變色的實(shí)例的相關(guān)資料,主要實(shí)現(xiàn)Android listveiw ItemClickListener寫入變色的功能,需要的朋友可以參考下2017-07-07
Arduino 數(shù)據(jù)類型轉(zhuǎn)換(單機(jī)片)詳細(xì)介紹
這篇文章主要介紹了Arduino 數(shù)據(jù)類型轉(zhuǎn)換(單機(jī)片)詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2016-11-11
Android攔截并獲取WebView內(nèi)部POST請求參數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了Android攔截并獲取WebView內(nèi)部POST請求參數(shù) 的實(shí)現(xiàn)方法,本文通過兩種方案給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04

