這篇“Android中如何提升ListView的性能”文章的知識點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Android中如何提升ListView的性能”文章吧。
創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),邳州企業(yè)網(wǎng)站建設(shè),邳州品牌網(wǎng)站建設(shè),網(wǎng)站定制,邳州網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,邳州網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
ListView如何運(yùn)作的?
ListView是設(shè)計應(yīng)用于對可擴(kuò)展性和高性能要求的地方。實(shí)際上,這就意味著ListView有以下2個要求:
盡可能少的創(chuàng)建View;
只是繪制和布局在屏幕上可見的子View。
理解***點(diǎn)很簡單:通過布局xml文件在創(chuàng)建View并顯示是很昂貴耗時耗資源的操作。盡管布局文件已經(jīng)編譯打包成了二進(jìn)制形式以便于更高效的語法解析,但是創(chuàng)建View仍然需要通過一個特殊的XML樹,并實(shí)例化所有需要響應(yīng)的View。
ListView通過回收一些不可見的Views,通常在Android源碼中稱為“ScrapView(廢棄的View)”來解決這個問題。這及意味著開發(fā)者只需要簡單的更新每行的內(nèi)容而不需要針對每個單獨(dú)的行的布局來創(chuàng)建View。
為了實(shí)現(xiàn)第二點(diǎn),在我們滑動屏幕時,ListView通過使用View回收器來增加低于或者高于當(dāng)當(dāng)前窗口的Views,并當(dāng)前活動的Views移動到一個可回收池中。這樣的話,ListView只需要在內(nèi)存中保持足夠多的Views去填充分配空間中的布局和一些額外的可回收Views,即使當(dāng)你的Adapter有上百個items的適合。它會使用不同的方法去填充行之間的空間,從頂部或者底部等等,具體取決于窗口是如何變化的。
下面這個圖很直觀的展示了當(dāng)你按下ListView的時候發(fā)生了什么:
通過上述介紹,相比我們已經(jīng)熟悉了ListView的這種機(jī)制,讓我們繼續(xù)前往技巧部分。正如上述介紹的,在滑動時,ListView通過動態(tài)的創(chuàng)建和回收很多View,實(shí)現(xiàn)了盡可能地讓Adapter的getView()輕量。所有的技巧都是通過多種方法讓getView()更快。
View的回收
當(dāng)ListView每次需要在屏幕上顯示新的一行的時候,會從其Adapter中調(diào)用getView()的方法。眾所周知,getView()方法有3個參數(shù):行的位置, convertView以及父ViewGroup。
參數(shù)convertView說穿來就是之前講述的ScrapView。當(dāng)ListView要求更新一行的布局時,convertView是一個非空值。因此,當(dāng)convertView值非空時,你僅僅需要更新內(nèi)容即可,而不需要重新一個新行的布局。getView()在Adapter中一般是如下的形式:
public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = mInflater.inflate(R.layout.your_layout, null); } TextView text = (TextView) convertView.findViewById(R.id.text); text.setText("Position " + position); return convertView; }
View Holder如何寫的模板
Android很常見的一個操作就是在布局文件中找到一個內(nèi)部的View。通常是使用一個findViewById()的View方法來實(shí)現(xiàn)的。這個findViewById()方法在View樹中,根據(jù)一個View ID,會遞歸的被調(diào)用來找到其子樹。雖然在靜態(tài)UI布局中使用findViewById()是完全正常的。但是,在滑動時,ListView調(diào)用其Adapter中的getView()是非常頻繁的。findViewById()可能會影響ListView滑動時的性能,尤其是你的行布局是很復(fù)雜的時候。
尋找一個充氣布局內(nèi)的內(nèi)部觀點(diǎn)是在Android上最常用的操作之一。這通常是通過一個名為findViewById(查看方法完成)。此方法將遞 歸經(jīng)過視圖樹尋找一個孩子用給定的ID碼。靜態(tài)的UI布局使用findViewById()是完全正常,但正如你所看到的,ListView中滾動時調(diào)用 適配器的getView()非常頻繁。 findViewById()可能perceivably擊中ListViews,尤其是滾動的性能,如果你行的布局是不平凡的。
View Holder的模式就是減少在Adapter中g(shù)etView()方法中調(diào)用findViewById()次數(shù)。實(shí)際上,View Holder是一個輕量級的內(nèi)部類,用于直接引用到所有內(nèi)部views。在創(chuàng)建View之后,你可以在每行的View存儲為一個標(biāo)簽。通過這種方法,只需要在初次創(chuàng)建布局的時候調(diào)用findViewById()。下面是一個使用上述方法的View Holder模板的代碼示例:
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.your_layout, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); convertView.setTag(holder); } else { holder = convertView.getTag(); } holder.text.setText("Position " + position); return convertView; } private static class ViewHolder { public TextView text; }
異步加載
很多時候,Android應(yīng)用在ListView每行中顯示一些多媒體內(nèi)容,比如圖片等。在Adapter中的getView()使用應(yīng)用內(nèi)置的圖片資源還是不會出什么問題的,因?yàn)榭梢源鎯υ贏ndroid的高速緩存中。但當(dāng)你想多態(tài)的顯示來自本地磁盤或網(wǎng)絡(luò)的內(nèi)容時,例如縮略圖,簡歷圖片等。在這種情況下,你可能不希望直接在Adapter中的getView()加載它們,因?yàn)镮O進(jìn)程會阻塞UI線程。如果這樣做的話,ListView就看起來非??D。
在一個單獨(dú)的線程,如果想要運(yùn)行的所有行的IO操作或任何高負(fù)載CPU限制的異步操作。其中的技巧就是要做到符合ListView的回收行為。例如,如果在Adapter中的getView()中,使用AsyncTask的加載去加載資料圖片,在AsyncTask完成之前,你正在加載的圖片View就有可能被回收用于其他地方。所以,一旦異步操作完成的同時,需要一種機(jī)制來知道如果相應(yīng)的View有沒有被回收。
一個簡單的方法來實(shí)現(xiàn)這一目標(biāo)是通過附加一些標(biāo)識該行與它相關(guān)的View的信息。然后,當(dāng)異步操作完成的適合,檢查目標(biāo)行的View和標(biāo)識的View是否一致。實(shí)現(xiàn)這一目標(biāo)的方法很多。下面是實(shí)現(xiàn)這種方法的一個很簡單的示例:
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; ... holder.position = position; new ThumbnailTask(position, holder) .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null); return convertView; } private static class ThumbnailTask extends AsyncTask { private int mPosition; private ViewHolder mHolder; public ThumbnailTask(int position, ViewHolder holder) { mPosition = position; mHolder = holder; } @Override protected Cursor doInBackground(Void... arg0) { // Download bitmap here } @Override protected void onPostExecute(Bitmap bitmap) { if (mHolder.position == mPosition) { mHolder.thumbnail.setImageBitmap(bitmap); } } } private static class ViewHolder { public ImageView thumbnail; public int position; }
以上就是關(guān)于“Android中如何提升ListView的性能”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
分享標(biāo)題:Android中如何提升ListView的性能
分享路徑:http://aaarwkj.com/article22/gdehjc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、ChatGPT、網(wǎng)站建設(shè)、外貿(mào)建站、品牌網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)