学习笔记4: ListView使用总结

本文深入探讨了ListView的优化技巧,包括重用convertView、使用viewHolders等方法减少资源消耗,并展示了ListView实现各种常用效果和布局调整。同时,文章还详细介绍了如何避免数据混乱问题以及在不同场景下使用ListView的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.ListView常用优化

重用convertView, 使用viewHolder setTag(),getTag()减少使用findViewByID

@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    ViewHolder holder = null;
    //判断是否缓存
    if(convertView == null){
        holder = new ViewHolder();
        //实例化布局
        LayoutInflater mInflater = LayoutInflater.from(lvActivity.this);
        convertView = mInflater.inflate(R.layout.lv_item_layout,null);
        holder.tv = (TextView)convertView.findViewById(R.id.textView);
        holder.iv = (ImageView)convertView.findViewById(R.id.imageView);
        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder)convertView.getTag();
    }
    holder.iv.setBackgroundResource(R.drawable.a);
    holder.tv.setText(getItem(i).toString());
    return convertView;
}

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

2.ListView的一些常用效果 (xml里面的listview标签下)

//无分隔线

android:divider="@null"

//灰色分隔线
android:divider="@android:color/darker_gray"
android:dividerHeight="10dp"

//没有滚动条
android:scrollbars="none"

//没有点击效果(系统默认会变成淡灰,这里也可以设成图片
android:listSelector="#00000000"

//添加刷新后,自动跳到刚才添加的那条

data.add(data.size(),"我是新来的");
adapter.notifyDataSetChanged();
lv.setSelection(N);

3.获取可见的某个item进行修改

int num = lv.getChildCount(); //获取可见的条目总数
View view1 = lv.getChildAt(3); //获取可见的第N个条目,注意:这个值不能大于num-1。 多了就会空指针
((TextView) view1.findViewById(R.id.textView)).setText("我被修改了"); //修改内容

4.滑动监听

lv.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (motionEvent.getAction()){
            case MotionEvent.ACTION_DOWN:
                Toast.makeText(lvActivity.this,"触摸屏幕",Toast.LENGTH_SHORT).show();
                break;
            case MotionEvent.ACTION_MOVE:
                Toast.makeText(lvActivity.this,"滑动",Toast.LENGTH_SHORT).show();
                break;
            case MotionEvent.ACTION_UP:
                Toast.makeText(lvActivity.this,"离开屏幕",Toast.LENGTH_SHORT).show();
                break;
        }
        return false;
    }
});

lv.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView absListView, int state) {
        switch (state) {
            case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                Toast.makeText(lvActivity.this,"离开屏幕1",Toast.LENGTH_SHORT).show();
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                Toast.makeText(lvActivity.this,"惯性滚动",Toast.LENGTH_SHORT).show();
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                Toast.makeText(lvActivity.this,"触摸屏幕1",Toast.LENGTH_SHORT).show();
                break;
        }
    }

    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        //滚动时一直回调
        //firstVisibleItem 当前可见的第一个Item的ID
        //visibleItemCount 当前可见的item 总数(显示一小半也算)
        //totalItemCount 整个listView的item 总数
    }
});

5.聊天ListView 及多种布局的ListView

a.准备好不同的布局文件

b.在适配器里多重写两个方法(这里只有2种type,随便写了下)
@Override
public int getItemViewType(int position) {
    if(position%2 == 0){
        return 1;
    }
    return 0;
}

@Override
public int getViewTypeCount() {
    return 2;
}
c.在getView()里面根据不同的type加载不同的布局,再设置内容就可以了
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    ViewHolder holder = null;
    //判断是否缓存
    if(convertView == null){
        holder = new ViewHolder();
        //根据不同的type加载布局
        LayoutInflater mInflater = LayoutInflater.from(chatActivity.this);
        if(getItemViewType(i)==1){
            convertView = mInflater.inflate(R.layout.chat_me, null);
        }
        else {
            convertView = mInflater.inflate(R.layout.chat_you, null);
        }
        holder.tv = (TextView)convertView.findViewById(R.id.textView);
        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder)convertView.getTag();
    }
    holder.tv.setText(getItem(i).toString());
    return convertView;
}

public final class ViewHolder{
    public TextView tv;
}

6.关于ListView里面数据混乱

网上有大量的经验,这里只做个人总结。
1.出现数据混乱的主要原因是在getView的时候重用了 convertView 和 viewHolder。
2.getView() 的时候会根据 item 数量的多少,重复的构造每一个item.
3.当我们滑动时,有的item消失,有的item出现。为了节省资源,系统会把消失的item当做容器,放入新item的内容展示出来。
4.在这个时候,我们会设置一些新的值。 而如果我们没有设置新的值,就会默认使用缓存里面的值。 所以就会数据混乱。
5.所以在使用listView的时候,最好保证convertview里的每一个内容都给了新的值,如果为空可以给个空值,这样不会出现混乱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值