第四章 ListView使用技巧

? ? ? ? ? ?ListView-------列表裹驰,他作為一個(gè)非常重要的顯示方式,不管是在Web中還是在移動(dòng)平臺(tái)中盖高,都是一個(gè)非常好的、不可或缺的展示信息的工具眼虱。在Android中喻奥,ListView控件接管了這一重任,在大量的場合下捏悬,我們都需要使用這個(gè)控件撞蚕。雖然在Android5.0時(shí)代,RecycleView在很多地方都在逐漸取代ListView过牙,但ListView的使用范圍依然非常廣泛甥厦,它這萬年大哥的地位也不是輕易就能撼動(dòng)的纺铭。本章將向大家展示如何高效的使用ListView。

? ? ? ? ? ?學(xué)習(xí)本章刀疙,你將了解到以下內(nèi)容:

? ? ? ? ? ListView常用技巧

? ? ? ? ? ListView常用拓展

4.1 ListView常用優(yōu)勢技巧

? ? ? ? ? ListView的基本用法相信大多數(shù)的讀者都已經(jīng)能夠非常熟練的使用了舶赔,下面我們著重學(xué)習(xí)一下使用ListView的技巧。

4.1.1 使用ViewHolder模式提高效率

? ? ? ? ?ViewHolder模式是提高ListView效率的一個(gè)很重要的方法谦秧。ViewHolder模式充分了ListView的視圖緩存機(jī)制竟纳,避免了每次在調(diào)用getView()的時(shí)候都去通過findViewBtId()實(shí)例化控件。據(jù)測試疚鲤,使用ViewHolder將提高50%以上的效率锥累。使用ViewHolder模式來優(yōu)化ListView非常簡單,只需要在自定義Adapter中定義一個(gè)內(nèi)部類ViewHolder集歇,并將布局中的控件作為成員變量桶略,代碼如下。


? ? ? ? ? ? 效果很簡單诲宇,這就是一個(gè)簡單的ListView际歼。

4.1.2 設(shè)置項(xiàng)目間分割線

? ? ? ? ? ? ?ListView的各個(gè)項(xiàng)目之間,可以通過設(shè)置分割線來進(jìn)行區(qū)分姑蓝,系統(tǒng)提供了divider和dividerHeight這樣兩個(gè)屬性來幫助我們實(shí)現(xiàn)這一功能鹅心。通過這兩個(gè)屬性,也可以控制listView之間的分割線和它的高度它掂,當(dāng)然巴帮,分割線不僅僅可以設(shè)置為一個(gè)顏色,同樣也可以設(shè)置為一個(gè)圖片資源虐秋,分割線的使用代碼如下所示榕茧。

? ? ? ? ? ?特殊情況下,當(dāng)設(shè)置分割線為如下代碼時(shí)客给,就可以把分割線設(shè)置為透明的了秩霍。

4.1.3 隱藏ListView的滾動(dòng)條

? ? ? ? ? ?默認(rèn)的ListView在滾動(dòng)時(shí)握巢,在右邊顯示滾動(dòng)條豆巨,指示當(dāng)前滑動(dòng)的位置压怠,我們可以設(shè)置scrollbars屬性控制ListView的滾動(dòng)條狀態(tài)。特別地桩引,當(dāng)設(shè)置scrollbars屬性為none的時(shí)候listview滾動(dòng)或者不滾動(dòng)們就都不會(huì)出現(xiàn)滾動(dòng)條了缎讼,代碼如下所示。

4.1.4 ?取消listview的item點(diǎn)擊效果

? ? ? ? ?當(dāng)點(diǎn)擊listview中的一項(xiàng)時(shí)坑匠,系統(tǒng)默認(rèn)會(huì)出現(xiàn)一個(gè)點(diǎn)擊效果血崭,在Android5.X上是一個(gè)波紋效果,而在Android5.X之下的版本則是一個(gè)改變北京顏色的效果,但可以通過修改listSelector屬性來取消點(diǎn)擊后的回饋效果夹纫,代碼如下所示咽瓷。

? ? ? ? 當(dāng)然,也可以直接使用Android自帶的透明效果來實(shí)現(xiàn)這個(gè)效果舰讹,代碼如下所示茅姜。

4.1.5 ? 設(shè)置ListView需要顯示在第幾項(xiàng)

? ? ? ? ? ListView以item為單位進(jìn)行顯示,默認(rèn)顯示在第一個(gè)item月匣,當(dāng)需要指定具體顯示的Item時(shí)钻洒,可以通過如下代碼來實(shí)現(xiàn)。

? ? ? ? ?其中N就是需要顯示的第N個(gè)Item桶错。

? ? ? ? ?當(dāng)然航唆,這個(gè)方法類似scrollTo胀蛮,是瞬間完成的移動(dòng)院刁。除此之外,還可以使用如下代碼來實(shí)現(xiàn)平滑移動(dòng)

4.1.6 動(dòng)態(tài)修改ListView

? ? ? ? ? ? ListView中的數(shù)據(jù)在某些情況下是需要變化的粪狼,當(dāng)然可以通過重新設(shè)置ListView的Adapter來更新ListView的顯示退腥,但這也就需要重新獲取一下數(shù)據(jù),相當(dāng)與重新創(chuàng)建ListView再榄,這樣顯然不是非常有好的狡刘,而且效率也不會(huì)太高。因此困鸥,可以使用一個(gè)更簡單的方法來實(shí)現(xiàn)ListView的動(dòng)態(tài)修改嗅蔬,代碼如下所示。

? ? ? ? ? ? ? 當(dāng)修改了傳遞給Adapter的映射的List之后疾就,只需要通過調(diào)用Adapter的notifyDataSetChanged()方法澜术,通知ListView更改數(shù)據(jù)源即可完成對ListView的動(dòng)態(tài)修改。不過猬腰,使用這個(gè)方法有一點(diǎn)需要注意的是鸟废,在使用Adapter.notifyDataSetChanged()方法時(shí),必須保證傳進(jìn)去Adapte的數(shù)據(jù)List是同一個(gè)List而不是其他對象姑荷,否則將無法實(shí)現(xiàn)該效果盒延。下面這個(gè)實(shí)例就演示了如何動(dòng)態(tài)地修改ListView。通過點(diǎn)擊按鈕鼠冕,不斷地給原有的List增加一個(gè)新的Item添寺,并調(diào)用notifyDataSetChanged()方法來實(shí)現(xiàn)ListView的動(dòng)態(tài)更新,完整代碼懈费。


4.1.7 遍歷ListView中的所有Item

? ? ? ? ? ? ?ListView作為一個(gè)ViewGroup计露,為我們提供了操縱子View的各種方法,最常用的就是通過getChldAt()來獲取第i個(gè)子View,代碼如下:

4.1.8 處理控ListView

? ? ? ? ? ? ?ListView用于展示列表數(shù)據(jù)薄坏,但當(dāng)列表中無數(shù)據(jù)時(shí)趋厉,ListView不會(huì)顯示任何數(shù)據(jù)或顯示,按照完善用戶體驗(yàn)的需求胶坠,這里應(yīng)該給以數(shù)據(jù)的提示君账。幸好,listView提供了一個(gè)方法-------setEmptyView()沈善,通過這個(gè)方法我們可以給ListView設(shè)置一個(gè)空數(shù)據(jù)下顯示的默認(rèn)提示乡数。包含listView的布局設(shè)置如下。

? ? ? ? ? ? 在代碼中闻牡,我們通過以下方式給ListView設(shè)置空數(shù)據(jù)是要顯示的布局净赴,代碼如下:

? ? ? ? ? ? 通過以上代碼,就給listView在空數(shù)據(jù)時(shí)顯示了一張默認(rèn)的圖片罩润,用來提示用戶玖翅;而在有數(shù)據(jù)時(shí),則不顯示

4.1.9 ListView滑動(dòng)監(jiān)聽

? ? ? ? ? ? listView的滑動(dòng)監(jiān)聽割以,是ListView中最重要的技巧金度,很多重寫的ListView,基本上都是在滑動(dòng)事件的處理上下功夫严沥,通過判斷滑動(dòng)見識(shí)進(jìn)行不同的邏輯處理猜极。而為了更加精確地監(jiān)聽滑動(dòng)事件,開發(fā)者通常還需要使用GestrueDetetor手勢識(shí)別消玄,VelocityTracker滑動(dòng)速度檢測等輔助類來完成更好的監(jiān)聽跟伏。這里介紹兩種監(jiān)聽ListView滑動(dòng)事件的方法,一個(gè)是通過onTouchListener來實(shí)現(xiàn)監(jiān)聽翩瓜,另外一個(gè)是使用OnscrollListener來實(shí)現(xiàn)監(jiān)聽受扳。

4.1.9.1 onTouchListener

? ? ? ? ? ? onTouchListener是View中的監(jiān)聽事件,通過監(jiān)聽ACTION_DOWN//觸摸時(shí)操作奥溺、ACTION_MOVE//移動(dòng)時(shí)操作辞色、ACTION_UP//離開時(shí)操作,這個(gè)三個(gè)事件發(fā)生時(shí)的坐標(biāo)浮定,就可以根據(jù)坐標(biāo)判斷用戶滑動(dòng)的方向相满,并在不同的事件中進(jìn)行相應(yīng)的邏輯處理,這種方式的使用代碼如下:

4.1.9.2 OnSorllListener

OnScrollListener是A bsListView中的監(jiān)聽事件桦卒,他封裝了很多與ListView相關(guān)的信息立美,使用起來也更加靈活。首先看一下OnScrollListener的一般用法方灾,代碼如下所示建蹄。




onScrollListener中有兩個(gè)會(huì)調(diào)方法---------onScrollStateChanged()和onScroll()碌更。

先來看一第一個(gè)方法onScrollStateChanged(),這個(gè)方法根據(jù)他的參數(shù)scrollState來決定器回調(diào)的此時(shí)洞慎,scrollState有以下三種模式有以下三種模式:

OnScrollListener.SCROLL_STATE_IDLE:正在滾動(dòng)痛单。

OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:正在滾動(dòng)時(shí)。

OnScrollListener.scroll_STATE_FLING:手指拋動(dòng)時(shí)劲腿,即手指用力滑動(dòng)旭绒,在離開后ListView由于慣性繼續(xù)滑動(dòng)的狀態(tài)。

當(dāng)用戶沒有左手指拋動(dòng)的狀態(tài)時(shí)焦人,這個(gè)方法只會(huì)回調(diào)2次挥吵,否則會(huì)回調(diào)3次,差別就是手指拋動(dòng)的這個(gè)狀態(tài)花椭。通常情況下忽匈,我們會(huì)在這個(gè)方法中通過不同的狀態(tài)來設(shè)置一些標(biāo)志Flag,來區(qū)分不同的滑動(dòng)狀態(tài)矿辽,供其他方法處理丹允。

下面再來看看onScroll()這個(gè)會(huì)調(diào)方法,他在ListView滾動(dòng)時(shí)會(huì)一直回調(diào)嗦锐,而這個(gè)方法中的后面三個(gè)int類型的參數(shù)嫌松,則非常精確地顯示了當(dāng)前ListView滾動(dòng)狀態(tài)沪曙,這三個(gè)參數(shù)如下所示奕污。

firstVisibleItem:但前能看見的第一個(gè)Item的ID(從0開始)。

visibleItemCount:當(dāng)前能看見的Item總數(shù)液走。

totaIItemCount:整個(gè)ListView的Item總數(shù)碳默。

這里需要注意的是,當(dāng)前能看見的Item數(shù)缘眶,包括沒有顯示完整的Item嘱根,即顯示一小半的Item也包括在內(nèi)了。通過這幾個(gè)參數(shù)巷懈,可以很方便地進(jìn)行一些判斷该抒,比如判斷是否滾動(dòng)到最后一行,就可以使用如下代碼進(jìn)行判斷顶燕,當(dāng)前可視的另一個(gè)Item的ID加上當(dāng)前可視Item的和等于Item總數(shù)的時(shí)候凑保,及滾動(dòng)到了最后一行。


再比如涌攻,可以通過如下代碼來判斷滾動(dòng)的方向欧引,代碼如下所示。

通過一個(gè)成員變量LastVisiblePosition來記錄上一次第一個(gè)可視的Item的ID并與當(dāng)前的可視Item的ID進(jìn)行比較恳谎,即可知道當(dāng)前滾動(dòng)的方向芝此。

要理解整個(gè)OnScrollListener憋肖,最好的方法還是在代碼中添加Log,并打印出狀態(tài)信息來進(jìn)行分析學(xué)習(xí)婚苹。在以上代碼中岸更,已經(jīng)添加了相應(yīng)的Log,對照Log進(jìn)行分析膊升,會(huì)很快撞我OnScrollListener的用法坐慰。

當(dāng)然,ListView也給我們提供了一些封裝的方法來獲取當(dāng)前可視的Item的位置等信息:

//獲取當(dāng)前可視區(qū)域內(nèi)最后一個(gè)Item的id

//獲取可視區(qū)域內(nèi)第一個(gè)Item的id

4.2 ? ListView常用拓展

ListView雖然使用廣泛用僧,但系統(tǒng)原生的ListView顯然是不能瞞住用戶在審美结胀、功能上不斷提高需求的。不過也不要緊责循,Android完全可以定制化糟港,讓我們非常方便對原生ListView進(jìn)行拓展、修改院仿。于是秸抚,在開發(fā)者的創(chuàng)新下,ListView越來越豐富多彩歹垫,各種各樣的基于原生ListView的拓展讓人目不暇接剥汤。下面來看幾個(gè)常用的ListView拓展。

4.2.1 具有彈性的ListView

Android默認(rèn)的ListView在滾動(dòng)到頂端或者底端的時(shí)候排惨,并沒有很好地提示吭敢。在Android5.X中,Google為這樣的行為只添加了一個(gè)半月的陰影效果暮芭,如圖4.4所示鹿驼。


而在IOS系統(tǒng)中,列表都是具有彈性的辕宏,及滾動(dòng)到低端或者頂端后會(huì)繼續(xù)往下或者往上滑動(dòng)一段距離畜晰。不得不說,這樣的設(shè)計(jì)的確更加友好瑞筐,雖然不知道Goolge為什么不模仿這樣的設(shè)計(jì)凄鼻,但我們可以自己修改ListView,讓ListView也可以“彈性十足”聚假。

块蚌。。魔策。匈子。。闯袒。虎敦。游岳。。



4.2.3 ?聊天ListView

通常我們使用的LIstView的每一項(xiàng)都具有相同的布局其徙,所以展示出來的時(shí)候胚迫,除了數(shù)據(jù)不同,只要你不隱藏布局唾那,其他的布局應(yīng)該是類似的访锻。為我們熟知的qq、微信等聊天App闹获,在聊天界面期犬,會(huì)展示至少兩種布局,即收到消息和自己發(fā)送的消息避诽,其實(shí)這樣的效果也是通過ListView來實(shí)現(xiàn)的龟虎,下面我們就來模仿一個(gè)聊天軟件列表界面,其效果如圖4.10所示:(就是聊天界面)


這樣一個(gè)Listview與我們平時(shí)所使用的ListView最大的不同沙庐,就是他擁有兩個(gè)不同的布局-----收到的布局鲤妥,和發(fā)送的布局。要實(shí)現(xiàn)這樣的效果拱雏,就需要拿ListView的Adapter“開刀”棉安。

在定義BaseAdapter的時(shí)候,需要去重寫它的getView()方法铸抑,這個(gè)方法就是用來獲取布局的贡耽,那么只需要在獲取布局的時(shí)候,判斷一下該獲取哪一個(gè)布局就可以了羡滑。而且ListView在設(shè)計(jì)的時(shí)候就已經(jīng)考慮到這種情況菇爪,所以它提供了連個(gè)方法,代碼如下柒昏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市熙揍,隨后出現(xiàn)的幾起案子职祷,更是在濱河造成了極大的恐慌,老刑警劉巖届囚,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件有梆,死亡現(xiàn)場離奇詭異,居然都是意外死亡意系,警方通過查閱死者的電腦和手機(jī)泥耀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛔添,“玉大人痰催,你說我怎么就攤上這事兜辞。” “怎么了夸溶?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵逸吵,是天一觀的道長。 經(jīng)常有香客問我缝裁,道長扫皱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任捷绑,我火速辦了婚禮韩脑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘粹污。我一直安慰自己扰才,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布厕怜。 她就那樣靜靜地躺著衩匣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪粥航。 梳的紋絲不亂的頭發(fā)上琅捏,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機(jī)與錄音递雀,去河邊找鬼柄延。 笑死,一個(gè)胖子當(dāng)著我的面吹牛缀程,可吹牛的內(nèi)容都是我干的搜吧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼杨凑,長吁一口氣:“原來是場噩夢啊……” “哼滤奈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撩满,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蜒程,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后伺帘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昭躺,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年伪嫁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了领炫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡张咳,死狀恐怖帝洪,靈堂內(nèi)的尸體忽然破棺而出似舵,到底是詐尸還是另有隱情,我是刑警寧澤碟狞,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布啄枕,位于F島的核電站,受9級特大地震影響族沃,放射性物質(zhì)發(fā)生泄漏频祝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一脆淹、第九天 我趴在偏房一處隱蔽的房頂上張望常空。 院中可真熱鬧,春花似錦盖溺、人聲如沸漓糙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昆禽。三九已至,卻和暖如春蝇庭,著一層夾襖步出監(jiān)牢的瞬間醉鳖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工哮内, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盗棵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓北发,卻偏偏與公主長得像纹因,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子琳拨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容