ListView學習之優化

(1).重寫適配器的getView方法時,getView方法有三個參數

public View getView(int position,View convertView,ViewGroup parent)

<span style="white-space:pre">	</span>有了這個參數,我們不必每調用一次getView,就重新加載一次佈局,

其中第二個參數convertView用於將之前加載好的佈局進行緩存。getView()方法列表子項滾動到屏幕內就會調用一次,用戶頻繁滑動就會頻繁的調用getView,所以裏面最好不要有很耗時的操作,比如每調用一次getView方法就重新加載一次佈局,當用戶頻繁的滑動列表時,頻繁的調用getView(),然後頻繁的重新加載佈局.....

我們可以用第二個參數,判斷一下是否有緩存,有的話直接重用,沒有就用inflate方法動態加載佈局。

public View getView(int position,View convertView,ViewGroup parent){

View mView;

if(convertView==null){//沒有緩存

mView=LayoutInflater.from(this).inflate(R.layout.list_item,null);

}

else{//有緩存,重用,不用inflate加載了

mView=convertView;

}

TextView textView=(TextView) mView.findViewById(R.id.text_view);

textView.setText("...");

return mView;

}



(2).在(1)的代碼中,如果用戶頻繁滑動列表,getView()方法頻繁調用,那麼上述代碼中TextView textView=(TextView) mView.findViewById(R.id.text_view)會在隨着getView()方法的調用,一次一次的獲取控件的實例。

public class xxAdapter extends ArrayAdapter<xx>{

.......

public View getView(int position,View convertView,ViewGroup parent){

View mView;

ViewHolder viewHolder;

if(convertView==null){

mView=LayoutInflater.from(this).inflate(R.layout.list_item,null);

viewHolder.textView=(TextView)findViewById(R.id.text_view);

mView.setTag(viewHolder)://將ViewHolder存儲到View中,setTag方法給View添加額外數據

}

else{

mView=convertView;

viewHolder=(ViewHolder) mView.getTag();//獲取原先存儲的ViewHolder

}

viewHolder.textView.setText("...");

return mView;

}

static class ViewHolder{//設置爲靜態,第一次加載會花費些時間,後面加載就方便了,而且只有一個ViewHolder,節省內存。

TextView textView;

}

}


擴展:關於上述代碼的setTag()方法,一個例子(給Button添加額外的數據以判斷是點擊的是哪個Button)

public class MyActivity extends Activity implements View.OnClickListener{

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

setContentView(R.layout.main_layout);

Button button1=(Button)findViewById(...);

button1.setTag(1);

Button button2=(Button)findViewById(...);

button2.setTag(2);

button1.setOnClickListener(this):

button2.setOnClickListener(this):

}


public void onClick(View v){

switch(v.getTag()){
case 1:

Toast.makeText(MyActivity.this,"1",Toast.LENGTH.SHORT).show();

break;

case 2:

Toast.makeText(MyActivity.this,"2",Toast.LENGTH.SHORT).show();

break;



}

}

}



(3)由於用戶滑動列表就會調用getView方法,所以getView方法不能做耗時操作,比如我們想在ListView裏面顯示我們從網站上獲取的圖片,加載圖片的方法不能放在getView方法中,可以進行異步處理。


(4)對於第三點,在加載圖片的情況下,當用戶來回上下滑動,就會一瞬間產生很多異步任務,也就是很多UI的更新操作,UI的更新發生在主線程中,有可能造成界面卡頓,而且這些大量的異步任務會造成線程池的擁堵。

我們可以等用戶滑動列表停下來時再進行加載圖片。

給ListView設置setOnScrollListener,   利用OnScrollListener的onScrollStateChanged方法判斷列表的狀態,是滑動還是停止,如果是滑動就不加載圖片,如果列表停止就加載圖片。

listView.setOnScrollListener(new AbsListView.OnScrollListener){

public void onScrollStateChanged(AbsListView view,int scrollState){

if(scrollState==OnScrollListener.SCROLL_STATE_IDLE) {

isStop=true;

xxAdapter.notifyDataSetChanged();

else{

isStop=false;

}

}

}


然後在xxAdapter的getView方法中判斷一下是否停止,停止時再加載圖片。



(5)開啓硬件加速,設置android:hardwareAccelerated="true"爲活動開啓硬件加速


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章