首页 > 代码库 > Andorid ListView使用技巧

Andorid ListView使用技巧

一、使用ViewHolder模式提高效率

  ViewHolder模式充分利用ListView的视图缓存机制,避免了每次在调用getView()方法的时候都去通过findViewById()方法实例化控件。使用ViewHolder模式,需要在自定义Adapter中定义一个内部类ViewHolder,并将布局中的控件作为成员变量。起始时,ListView创建的Cell条数量是当前屏幕显示的Cell条数,在向上滚动时,新显示的Cell是滚出屏幕的Cell的复用。与iOS的TableView的Cell优化一样。

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 =http://www.mamicode.com/ data; 9         mInflater = LayoutInflater.from(context);10     }11 12     @Override13     public int getCount()14     {15         return mData.size();16     }17 18     @Override19     public Object getItem(int position)20     {21         return mData.get(position);22     }23 24     @Override25     public long getItemId(int position)26     {27         return position;28     }29 30     @Override31     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         else45         {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 ViewHolder56     {57         public ImageView mImgView;58         public TextView mTitle;59     }60 }

 

二、设置项目间分隔线

  系统提供了divider(颜色)和dividerHeight(高度)这两个属性实例ListView项目间分隔线。

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

  设置透明分隔线:

1 android:divider="@null"

 

三、隐藏ListView的滚动条

  ListView在滚动时,默认在右侧显示滚动条,可以通过scrollbars属性设置不显示滚动条:

1 android:scrollbars="none"

 

四、取消ListView的Item点击效果

  通过listSelector属性设置Cell选中后的颜色:

1 android:listSelector="#000000"

  使用系统自带的透明色来实现:

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

 

五、动态修改ListView

  ListView中的数据在某些情况下是需要变化的,当然可以通过重新设置ListView的Adapter来更新ListView的显示,但是,这需要重新获取数据,相当于重新创建ListView。可以通过以下方法实现动态更新ListView数据显示:

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

  PS:当修改了传递给Adapter的映射List之后,只需要通过调用Adapter的notifyDataSetChanged()方法,通过ListView更新数据源即可完成对ListView的动态修改。

 

六、遍历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 }

 

七、处理空ListView

  在列表无数据时,ListView不显示数据或者提示,ListView提供了setEmptyView()方法,通过这个方法可以给ListView设置一个空数据下显示的默认提示。代码如下所示:

1 // list view2 mListView = (ListView) findViewById(R.id.listview);3 mHolderAdapter = new ViewHolderAdapter(this, mData);4 mListView.setAdapter(mHolderAdapter);5 // 获取在空List时,显示的View6 mNotDataView = (TextView) findViewById(R.id.emptyListview);7 // 设置ListView在空数据时,显示的View8 mListView.setEmptyView(mNotDataView);

 

八、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 @Override31 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的id2 mListView.getLastVisiblePosition();3 // 获取可视区域内的第一个Item的id4 mListView.getFirstVisiblePosition();

 

  

Andorid ListView使用技巧