日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Android筆記

 ghappy 2012-10-21

Why ListView?

ListView 如果僅僅出于功能上的需求ListView可能沒有存在的必要,ListView能作的事情基本上ScrollView也能勝任。ListView存在的最根本的原因在于它的高效(如何實現(xiàn)的?).ListView通過對象的復(fù)用從而減少內(nèi)存的消耗,也減少了對象的創(chuàng)建從而也減少的cpu的消耗(在Androidk中創(chuàng)建View對象經(jīng)常伴隨著解析xml)。ListView的本質(zhì)是一張bitmap(當(dāng)然所有的控件文字等在屏幕上看到的最終都會變成bitmap),ListView會按照需求,根據(jù)Adapter提供的信息把需要的Item畫出來顯示在屏幕上,當(dāng)屏幕滾動的時候會重新計算Item的位置并繪制出新的bitmap顯示在屏幕上。這樣聽起來感覺可能不是很高效,但這樣帶的好處就是,每用為一第個Item 創(chuàng)建一個View對象,樣式一樣的對象可以共用一個View對象,減少了內(nèi)存的消耗。而且ListView是事件驅(qū)動的,只有當(dāng)需要的時候才會重新繪制,并且只會 繪制當(dāng)前屏幕上所顯示的Items.

How To Use?

ListView 離不開Adapter,通常的作法創(chuàng)建一個類繼承BaseAdapter,Override getCount()和getView()等方法。生成這個類的對象,調(diào)用ListView的setAdapter()與ListViw進(jìn)行綁定。

How Does It work?

ListView會調(diào)用跟其綁定的Adapter的getCount()方法知道有多少個Item需要展示,然后循環(huán)調(diào)用getView(int position, View convertView, ViewGroup parent)知道第position個Item該怎么畫,并畫出來直到把當(dāng)前的ListView的空間填滿。當(dāng)Adapter當(dāng)中的數(shù)據(jù)改變時,需調(diào)用notifyDataSetChanged ()告訴Adapter數(shù)據(jù)發(fā)生了變化或者給Adapter注冊一個觀察者registerDataSetObserver (DataSetObserver observer)。當(dāng)Adapter得知與其綁定的數(shù)據(jù)己發(fā)生改變時間,會再次調(diào)用getCount()方法,并循環(huán)調(diào)用getView(int position, View convertView, ViewGroup parent)刷新當(dāng)前頁面。

Item 1

Item 2

Item 3

Item 4

Item 5

Item 6

Item 7

Item 8

當(dāng)這個ListView 向上滾動需要創(chuàng)建一個Item9 同時,有些對象(比如Item1 )不在顯示區(qū)域?qū)⒖床坏剑@時android 將會把item1 的 引用傳遞給 Adapter.getView() 中的convertView這樣我們就不用再創(chuàng)建一個View來存放Item9,只需要把原來的item1對象作下修改,就可以重復(fù)使用了 ;我們也不用擔(dān)心convertView 是不是正確的類型,這個由系統(tǒng)保證,所以我們要作的就是把convertView 轉(zhuǎn)換(經(jīng)常需要向下轉(zhuǎn)型)成我們自己的View 再給它賦值,in this case :(TextView) convertView.setText(“Item9”);

復(fù)制代碼
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
//this would be first time to show the item,so we need to create it
convertView = mInflater.inflate(R.layout.item, null);
}
//we grab the convertView,modify it and reuse it
((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);
return convertView;
}
復(fù)制代碼

調(diào)用方法所需要的消耗要比訪問變量高得多,而上面的代碼一次又一次的調(diào)用findViewById()方法,作著重復(fù)的事情。所以我們可以進(jìn)一步進(jìn)行如下優(yōu)化: 創(chuàng)建一個類用來保存一些View的引用,這樣我們就可以直接使用,而不用再調(diào)用findViewById().因為我們所保存的只是引用不是對象本身,所以不用擔(dān)心會占用大量內(nèi)存

復(fù)制代碼
static class ViewHolder {
TextView text;
ImageView icon;
}

public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView
= mInflater.inflate(R.layout.list_item_icon_text, null);
holder
= new ViewHolder();
holder.text
= (TextView) convertView.findViewById(R.id.text);
holder.icon
= (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
else {
holder
= (ViewHolder) convertView.getTag();
}
//we store the reference ,so that we don’t have to call findViewById() over and over again
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position
& 1) == 1 mIcon1 : mIcon2);
return convertView;
}
復(fù)制代碼

上圖是T-mobile g1上采集的的數(shù)據(jù),現(xiàn)在看來可能現(xiàn)在不是很準(zhǔn)確,但其性能上的差異還是很有參考價值的。

Tips & Tricks

ListView是為了大容量數(shù)據(jù)展示而設(shè)計的。如果數(shù)據(jù)量(Item的數(shù)量)不是很大,且用ListView實現(xiàn)起來比較麻煩,不妨換種思路,不使用ListView,而用ScrollView來實現(xiàn)。

如果Item信息布局比較復(fù)雜或者Item的數(shù)量很多,出于性能的考慮,建議自定義一個View組件實現(xiàn)需要的功能,而不是組合其它控件達(dá)到所要的效果。

ListView滾動變黑:在xml中給ListView增加一個屬性android:cacheColorHint="#00000000" 。當(dāng)ListVIew中有很多Item,有時候需要快速的滾動。比如從第一個Item滾動到第600個Item這個時候,中間的很多Item對用戶來說意義不是很大,但android卻要調(diào)用 adapter.getView()方法將這些Item逐一畫出,并且因為滾動很快用戶不希望有任何的延遲。這在一些低端手機比如g1,是很難作到的。所以google工程師想出的一個辦法是在滾動的時候,讓屏幕變黑用一張黑色bitmap蓋住ListView,而不去繪制中間過程中的很多Item,從而提升性能。

Item有自己的背景蓋住了Selector光標(biāo):在xml中給ListView增加一個屬性:android:drawSelectorOnTop="true"這樣光標(biāo)就會跑到Item上面的圖層,解決我們的問題。

Snippets

多選框ListView

   

帶有進(jìn)度條的ListView,多個子線程刷新各自的進(jìn)度,如果子線程很多那么刷新就會變得很頻繁,我們可以由一個handler負(fù)責(zé)統(tǒng)一刷新,這樣我們就要以增加一些額外條件限制刷新的次數(shù)和條件

分批加載的原理很簡單,給ListView添加一個OnScrollListener監(jiān)聽滾動事件,當(dāng)用戶滾動到屏幕到特定的位置時加載新數(shù)據(jù),并給LIstView加一個正在加載的footerView,當(dāng)加載數(shù)據(jù)結(jié)束時再把這個footerView去掉。

如果有什么疑問,發(fā)現(xiàn)bug或者有更好的想法或者建議,或者附件無法下載。請發(fā)郵件至arthurbrown@163.com

工程源碼

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多