ListView使用技巧

       虽然在Android 5.X时代,RecyclerView在很多地方都在逐渐取代ListView,但是毕竟ListView要成熟很多,所以还是有必要熟练掌握的。

       ListView常用优化技巧

       1.使用ViewHolder模式提高效率

 ViewHolder模式是提高ListView效率的一个很重要的方法。ViewHolder模式充分利用了ListView的视图缓存机制,避免了每次在调用getView()的时候都去通过findViewById实例化控件。

/**
 * 自定义Adapter
 * Created by LGL on 2016/3/10.
 */
public class MyAdapter extends BaseAdapter {

    private List<String> mData;
    private LayoutInflater mInflater;

    //构造方法
    public MyAdapter(Context context, List<String> mData) {
        this.mData = mData;
        mInflater = LayoutInflater.from(context);
    }

    //返回长度
    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        //判断是否有缓存
        if (convertView == null) {
            viewHolder = new ViewHolder();
            //通过LayoutInflater去实例化布局
            convertView = mInflater.inflate(R.layout.item, null);
            viewHolder.img = (ImageView) convertView.findViewById(R.id.img);
            viewHolder.tv = (TextView) convertView.findViewById(R.id.tv);
            convertView.setTag(viewHolder);
        } else {
            //通过TAG找到缓存的布局
            viewHolder = (ViewHolder) convertView.getTag();
        }
        //设置布局中要显示的东西‘
        viewHolder.tv.setText(mData.get(position));
        return convertView;
    }

    public final class ViewHolder {
        public ImageView img;
        public TextView tv;
    }
}

     2.设置项目间分隔线

      ListView的各个item之间,可以通过设置分割线来进行区分,系统提供了divider和dividerHeight这样两个属性来帮助我们实现这一功能。通过这两个属性,也可以控制ListView之间的分隔线和它的高度。当然,分隔线不仅仅可以设置为一个颜色,同样也可以设置为一个图片资源。

android:dividerHeight="10dp"
android:divider="@android:color/holo_blue_bright"

但是如果你是需要去掉这个分割线的话,其实也好办

 android:divider="@null"

     3.隐藏ListView的滚动条

android:scrollbars="none"

      4.取消ListView的Item点击效果

   当点击ListView中的一项时,系统默认会出现一个点击效果,在Android5.x上是一个波纹效果,而在Android5.X之下的版本则是一个改变背景颜色的效果,但可以通过listSelector属性来取消掉点击后的回馈效果。

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

或你也可以直接填#00000000

      5.设置ListView需要显示在第几页

    ListView以Item为单位进行显示,默认显示在第一个Item,当需要指定具体显示的Item时,可以通过:

listview.setSelection(N);//N表示第几个item

     当然这个方法类似scrollTo,是瞬间完成的移动。除此之外,还可以进行平滑的移动:

listview.smoothScrollBy(distance,duration);
listview.smoothScrollByOffset(offset);
listview.smoothScrollToPosition(index);

       6.动态修改ListView

list.add("我是新增加的数据");
//通知刷新
myAdapter.notifyDataSetChanged();

      7.遍历ListView中的所有Iitem

  ListView作为一个ViewGroup,为什么提供了操纵子View的各种方法,最常用的就是通过getChildAt()来获取第i个子View

for (int j = 0; j < listview.getChildCount();j++){
 View v = listview.getChildAt(12);
 }

    8.处理空ListView

   ListView用于展示列表数据,但当列表中无数据时,ListView不会显示任何数据或提示,按照完善用户体验的需求,这个应该给以无数据的提示。ListView提供了一个方法---------setEmptyView(),通过这个方法我们可以给ListView设置一个空数据下显示的默认提示。

listview.setEmptyView(findViewById(R.id.tv_null));

  9.ListView滑动监听

       ListView的滑动监听,是ListView中最重要的技巧,很多重写ListView,基本上都是在滑动事件上下功夫,通过判断滑动事件进行不同的逻辑处理。而为了更加精确地监听滑动事件,开发者通常还需要使用GestureDetector手势识别、VelocityTracker滑动速度检测等辅助类来完成更好地监听。这里介绍两种监听ListView滑动事件的方法,一个是通过onTouchListener来实现监听,另一个是使用OnScrollListener来实现监听。

  

OnTouchListener

      OnTouchListener是View的监听事件,通过监听ACTION_DOWN,UP,MOVE这三个事件发生时的坐标,就可以根据坐标判断用户滑动的方向,并在不同的事件中进行相应的逻辑处理,这种方式的使用代码:

listview.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //触摸时操作
                        break;
                    case MotionEvent.ACTION_MOVE:
                        //移动时操作
                        break;
                    case MotionEvent.ACTION_UP:
                        //离开时操作
                        break;
                }
                return true;
            }
        });

   OnScrollListener

OnScrollListener是AbsListView的监听事件,他封装了很多ListView的相关信息,所以用起来很灵活

 listview.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {
                               switch (i) {
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                        //滚动停止
                        break;
                    case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                        //正在滚动
                        break;
                    case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                        //手指抛动时,即手指用力滑动的时候
                        break;
                }
            }

            @Override
            public void onScroll(AbsListView absListView, int i, int i1, int i2) {
                    //滚动的时候一直在调用
            }
        });

       OnScrollListener中有两个回调方法onScrollStateChanged()和onScroll

 

  • OnScrollListener.SCROLL_STATE_IDLE://滚动停止
  • OnScrollListener.SCROLL_STATE_TOUCH_SCROLL://正在滚动
  • OnScrollListener.SCROLL_STATE_FLING://手指抛动时,即手指用力滑动的时候

当用户没有做手指抛动的动作时,这个方法只会调用2次,否则就调用三次,差别就在于手指抛动的这个状态,通常情况下,我们会在这个方法中通过不同的状态来标注一些FLAG,我们来看下onScrill()这个方法

 

 /**
                 * firstVisibleItem:表示在现时屏幕第一个ListItem(部分显示的ListItem也算)在整个ListView的位置(下标从0开始)
                 * visibleItemCount:表示在现时屏幕可以见到的ListItem(部分显示的ListItem也算)总数
                 * totalItemCount:表示ListView的ListItem总数
                 * listView.getFirstVisiblePosition()表示在现时屏幕第一个ListItem(第一个ListItem部分显示也算)在整个ListView的位置(下标从0开始)
                 * listView.getLastVisiblePosition()表示在现时屏幕最后一个ListItem(最后ListItem要完全显示出来才算)在整个ListView的位置(下标从0开始)
                 */
if(i+i1 == i2 &&i2>0){
     //滚动到最后一行
     }
 int i3 = i;
 if(i>i3){
     //上滑
  }else if(i<i3){
     //下滑
  }
//获取可视区域内最后一个item的id
listview.getLastVisiblePosition();
 //获取可视区域内第一个item的id
 listview.getFirstVisiblePosition();

 ListView常用拓展

  具有弹性的ListView

  Android默认的ListView在滚动到顶端或者低端的时候,并没有很好的提示。在Android 5.X中,Google为这样的行为只添加了一个半月形的阴影效果。

    而在IOS系统中,列表都是具有弹性的,即滚动到底端或者顶端后会继续往下或者往上滑动一段距离。不得不说,这样的设计的确更加的友好,虽然不知道Google为什么不模仿这样的设计,但我们可以自己修改ListView。

   我们在查看ListView的源码的时候会发现一个控制滑动到边缘的处理方法

@Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

我們可以看到这样一个参数maxOverScrollY,就是他负责控制滑动的个数的,默认是0,我们重写ListView

/**
 * 弹性ListView
 * Created by lgl on 16/3/20.
 */
public class ListViewScroll extends ListView {

    private int mMaxOverdistance =100;

    public ListViewScroll(Context context, AttributeSet attrs) {
        super(context, attrs);

        //通过分辨率来调节滑动尺度
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        float density = metrics.density;
        mMaxOverdistance = (int)(density*mMaxOverdistance);

    }


    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, mMaxOverdistance, maxOverScrollY, isTouchEvent);
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值