Andorid ListView使用技巧

1、使用ViewHolder模式提升效率

  ViewHolder模式充分利用ListView的視圖緩存機制,避免了每次在調用getView()方法的時候都去經過findViewById()方法實例化控件。使用ViewHolder模式,須要在自定義Adapter中定義一個內部類ViewHolder,並將佈局中的控件做爲成員變量。起始時,ListView建立的Cell條數量是當前屏幕顯示的Cell條數,在向上滾動時,新顯示的Cell是滾出屏幕的Cell的複用。與iOS的TableView的Cell優化同樣。android

1. 示例緩存

 1 public class ViewHolderAdapter extends BaseAdapter
 2 {
 3     private List<String> mData;
 4     private LayoutInflater mInflater;
 5 
 6     public ViewHolderAdapter(Context context, List<String> data)
 7     {
 8         mData = data;
 9         mInflater = LayoutInflater.from(context);
10     }
11 
12     @Override
13     public int getCount()
14     {
15         return mData.size();
16     }
17 
18     @Override
19     public Object getItem(int position)
20     {
21         return mData.get(position);
22     }
23 
24     @Override
25     public long getItemId(int position)
26     {
27         return position;
28     }
29 
30     @Override
31     public View getView(int position, View convertView, ViewGroup parent)
32     {
33         ViewHolder holder = null;
34         // 判斷是否緩存
35         if (convertView == null)
36         {
37             holder = new ViewHolder();
38             // 經過LayoutInflater實例化佈局
39             convertView = mInflater.inflate(R.layout.viewholder_item, null);
40             holder.mImgView = (ImageView) convertView.findViewById(R.id.icon);
41             holder.mTitle = (TextView) convertView.findViewById(R.id.title);
42             convertView.setTag(holder);
43         }
44         else
45         {
46             holder = (ViewHolder) convertView.getTag();
47         }
48 
49         holder.mImgView.setBackgroundResource(R.mipmap.ic_launcher);
50         holder.mTitle.setText(mData.get(position));
51 
52         return convertView;
53     }
54 
55     public final class ViewHolder
56     {
57         public ImageView mImgView;
58         public TextView mTitle;
59     }
60 }

 

2、設置項目間分隔線

  系統提供了divider(顏色)和dividerHeight(高度)這兩個屬性實例ListView項目間分隔線。ide

1 android:divider="@android:color/darker_gray"
2 android:dividerHeight="10dp"

  設置透明分隔線:佈局

1 android:divider="@null"

 

3、隱藏ListView的滾動條

  ListView在滾動時,默認在右側顯示滾動條,能夠經過scrollbars屬性設置不顯示滾動條:優化

1 android:scrollbars="none"

 

4、取消ListView的Item點擊效果

  經過listSelector屬性設置Cell選中後的顏色:this

1 android:listSelector="#000000"

  使用系統自帶的透明色來實現:spa

1 android:listSelector="@android:color/transparent"

 

5、動態修改ListView

  ListView中的數據在某些狀況下是須要變化的,固然能夠經過從新設置ListView的Adapter來更新ListView的顯示,可是,這須要從新獲取數據,至關於從新建立ListView。能夠經過如下方法實現動態更新ListView數據顯示:code

1 mData.add("test");
2 mHolderAdapter.notifyDataSetChanged();

  PS:當修改了傳遞給Adapter的映射List以後,只須要經過調用Adapter的notifyDataSetChanged()方法,經過ListView更新數據源便可完成對ListView的動態修改。blog

 

6、遍歷ListView中全部的Item

  ListView做爲一個ViewGroup,提供了各類操縱子View的方法,最經常使用的就是經過getChildAt()方法獲取第i個子View,代碼以下所示:事件

1 for (int idx = 0; idx < mListView.getChildCount(); idx++)
2 {
3     View view = mListView.getChildAt(idx);
4 }

 

7、處理空ListView

  在列表無數據時,ListView不顯示數據或者提示,ListView提供了setEmptyView()方法,經過這個方法能夠給ListView設置一個空數據下顯示的默認提示。代碼以下所示:

1 // list view
2 mListView = (ListView) findViewById(R.id.listview);
3 mHolderAdapter = new ViewHolderAdapter(this, mData);
4 mListView.setAdapter(mHolderAdapter);
5 // 獲取在空List時,顯示的View
6 mNotDataView = (TextView) findViewById(R.id.emptyListview);
7 // 設置ListView在空數據時,顯示的View
8 mListView.setEmptyView(mNotDataView);

 

8、ListView滑動監聽

  1. OnTouchListener是View中的監聽事件,經過監聽ACTION_DOWN、ACTION_MOVE、ACTION_UP這三個事件發生時的座標,就能夠根據座標判斷用戶滑動的方向:

 1 mListView.setOnTouchListener(new View.OnTouchListener()
 2 {
 3     @Override
 4     public boolean onTouch(View v, MotionEvent event)
 5     {
 6         switch (event.getAction())
 7         {
 8             case MotionEvent.ACTION_DOWN:
 9             {
10                 // 觸摸時操做
11                 Log.d(TAG, "Down");
12                 break;
13             }
14             case MotionEvent.ACTION_MOVE:
15             {
16                 // 移動時操做
17                 Log.d(TAG, "Move");
18                 break;
19             }
20             case MotionEvent.ACTION_UP:
21             {
22                 // 手指離開屏幕時操做
23                 Log.d(TAG, "Up");
24                 break;
25             }
26         }
27         return false;
28     }
29 });

 

  2. OnScrollListener是AbsListView中的監聽事件,通常經常使用方法, 以下代碼所示:

 1 mListView.setOnScrollListener(new AbsListView.OnScrollListener()
 2 {
 3 @Override
 4 public void onScrollStateChanged(AbsListView view, int scrollState)
 5 {
 6     switch (scrollState)
 7     {
 8         case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
 9         {
10             // 滑動中止時
11             Log.d(TAG, "SCROLL_STATE_IDLE");
12             break;
13         }
14         case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
15         {
16             // 正在滾動
17             Log.d(TAG, "SCROLL_STATE_TOUCH_SCROLL");
18             break;
19         }
20         case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
21         {
22             // 手指拋開時,即手指用力滑動,在離開後ListView因爲慣性繼續滑動
23             Log.d(TAG, "SCROLL_STATE_FLING");
24             break;
25         }
26     }
27 }
28 
29 int lastVisibleItemPosition = 0;
30 @Override
31 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
32 {
33     // 滾動時,一直調用
34     Log.d(TAG, "onScroll");
35 
36     // 判斷滾動方向
37     if (firstVisibleItem > lastVisibleItemPosition)
38     {
39         // 向上滾動
40         Log.d(TAG, "Scroll Up");
41     }
42     else if (firstVisibleItem < lastVisibleItemPosition)
43     {
44         // 向下滾動
45         Log.d(TAG, "Scroll Down");
46     }
47     lastVisibleItemPosition = firstVisibleItem;
48 }
49 });

 

  • AbsListView.OnScrollListener.SCROLL_STATE_IDLE:滾動中止時
  • AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:正在滾動;
  • AbsListView.OnScrollListener.SCROLL_STATE_FLING:手指拋開時,即手指用力滑動,在離開後ListView因爲慣性繼續滑動;

  在ListView滾動時會一直回調,而方法中的後三個int類型的參數,則很是精確的顯示了當前ListView滾動的狀態,這三個參數以下所示:

  • firstVisibleItem:當前能看見的第一個Item的id(從0開始);
  • visibleItemCount:當前能看見的Item個數;
  • totalItemCount:當前ListView的Item總數;

  在ListView中還有一些其它的方法,以下代碼所示:

1 // 獲取可視區域內最後一個Item的id
2 mListView.getLastVisiblePosition();
3 // 獲取可視區域內的第一個Item的id
4 mListView.getFirstVisiblePosition();
相關文章
相關標籤/搜索