關於ListView的getView方法被多次重複呼叫的問題
package com.pxy.demo.adapter;
import java.util.ArrayList;
import com.pxy.demo.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
public class MyAdapter extends BaseAdapter{
private ArrayList<String> list;
private Context context;
public MyAdapter(Context context,ArrayList<String> list) {
super();
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list == null? 0 :list.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
ViewHolder holder = null;
System.out.println("view = "+v + " position = " + position);
if(v == null){
System.out.println("view = null 時進入方法");
holder = new ViewHolder();
v = LayoutInflater.from(context).inflate(R.layout.item, null);
holder.mButton = (Button) v.findViewById(R.id.btn);
v.setTag(holder);
}else{
holder = (ViewHolder) v.getTag();
}
String str = list.get(position);
if(str!=null){
holder.mButton.setText(str);
}
return v;
}
private class ViewHolder {
Button mButton;
}
}
執行時會發現getView會被重複呼叫多次,假設list.size()=10,getView被呼叫的次數會大於10,原因是當ListView的高度是固定的或者match_parent的時候,listview很容易就能計算出容器內可以顯示多少行。但如果我們使用了“wrap_content,只有在螢幕內控制元件完全載入後才知道到底能顯示多少行資料時,ListView自身便會做一些嘗試性計算,就會導致重複呼叫多次getView(具體請看log輸出日誌)。
具體原因:View在Draw的時候分成兩個階段:measure和layout,在measure階段時主要就是為了計算兩個引數:height和width。而且要注意的是,這是個遞迴的過程,從頂向下,DecorView開始依次呼叫自己子元素的measure。計算完成這兩個引數後就開始layout,最後再是draw的呼叫。對於ListView,當然每一個Item都會被呼叫measure方法,而在這個過程中getView和getCount會被呼叫,而且看使用者的需求,
可能會有很多次呼叫。而為什麼會有很多組次呼叫呢?問題就在於在layout中的決定ListView或者它的父元素的height和width屬性的定義了。match_parent會好一點,計算方法會比較簡單,只要跟父元素的大小相似就行,但是即使是match_parent,也不能給View當飯吃,還是要計算出來具體的dip,所以measure還是會被呼叫,只是可能比wrap_content的少一點。至於自適應的它會一直考量它的寬和高,根據內容(也就是它的子Item)計算寬高。可能這個measure過程會反覆執行,如果父元素也是wrap_content,這個過程會更加漫長。所以,解決方法就是儘量避免自適應,除非是萬不得已,固定大小或者填充的效果會比較好一些。
listview,gridview,有時候getview會呼叫多次,特別是把listview放在viewpager中,很容易卡頓
網上的方法往往只是說,把listview的height固定住或者fill_parent,其實這樣簡單的listview是有效的,但是item如果是複雜的xml,很難實現,或者說無法實現。
究其原因,無非是listview要動態計算有多少個view顯示在裡面,所以需要多次onMeasure,最後才onLayout,而onMeasure可能需要執行多次
這不就行了,我們在adapt裡面的getview中,判斷是否在onmeasure裡,如果在,那麼僅僅mInflater.inflate(R.layout.XXX),然後立刻返回這個
convertView,如果不在onmeasure裡,那麼再去真正的onlayout.
結合這種方法,成功解決了卡頓問題..
相關文章
- Android ListView的getview()中重複呼叫(position重複呼叫)AndroidView
- 解決直播商城原始碼中,getView被重複呼叫原始碼View
- 關於SQL的重複記錄問題SQL
- mysql多次呼叫儲存過程的問題MySql儲存過程
- 關於Corba呼叫的Timeout 問題ORB
- 一個關於SessionBean呼叫的問題。SessionBean
- getView()不復用convertView,ListView即毫無複用!(ListView回收機制)View
- 關於Partition列被更新的問題
- Java 面試題關於方法的重寫Java面試題
- 關於GIT push的時候要重複輸入密碼的問題Git密碼
- 【java】ObjectOutputStream & ObjectInputStream 多次寫入發生重複寫入相同資料的問題JavaObject
- 一個關於值傳遞呼叫的問題
- 有重複元素的排列問題
- 關於在 Angular 應用裡重複呼叫 RouterModule.forRoot(ROUTES) 的討論Angular
- Compose NavHost跳轉頁面時多次重組的問題
- 資料檢視的重複問題
- RabbitMQ如何解決被重複消費和資料丟失的問題?MQ
- 重複登入問題最終解決方法
- 面試中可能會被問到的幾個關於“委託”的問題面試
- 關於ajax提交表單,重複提交解決方法
- 被騰訊問蒙的各種Redis複雜問題Redis
- 關於非同步介面呼叫的疑問?非同步
- sql重複插入問題SQL
- 併發請求的重複插入問題
- 解決表單重複提交的問題
- strust2 重複提交的問題Rust
- Adapter的getView方法詳解APTView
- 關於SQLServerDriver的問題SQLServer
- 關於 JavaMail 的問題JavaAI
- 關於session的問題Session
- 關於requests的session方法無法保持cookie的問題。SessionCookie
- 重寫ListView解決ListView內部ViewPaper滑動事件衝突問題View事件
- 關於防止同一程式多次執行的破解方法--答hkip的提問 (3千字)
- 有關 Android Studio 重複引入包的問題和解決方案Android
- 請教關於已經完成專案重構的問題!
- 關於多執行緒訪問靜態方法的問題執行緒
- 關於在基於spring的框架中使用static 方法的問題Spring框架
- EasyUI中那些不容易被發現的坑——EasyUI重複請求2次的問題UI