• 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 = 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 }

    二、设置项目间分隔线

      系统提供了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 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);

    八、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();

      

  • 相关阅读:
    Monkey面试整理
    Monkey测试环境搭建
    软件测试之Monkey 初步了解(入门级)
    接口测试Post和Get区别(面试题)
    软件测试测试人员遇到的问题及解决方法(面试)
    接口测试用例的基本测试点
    兼容性测试主要测的浏览器
    【转】Web测试中定位bug方法
    使用Postman做接口测试
    head中的title显示在body中
  • 原文地址:https://www.cnblogs.com/naray/p/5627275.html
Copyright © 2020-2023  润新知