【Android】ListView使用BaseAdapter异常显示小结

  • ListView和Adapter的基础知识

【问】假如Listview的item数量有10亿条的话岂不是要绘制10亿个View?

【答】肯定不可能,手机内容会没那么大...Android针对这种情况专门设计了Recycler的构件

【参考】http://www.cnblogs.com/xiaowenji/archive/2010/12/08/1900579.html

【概要】

假如一个页面只能显示10条list内容,且每个条目的样式是一样的

那么50条内容的显示,其实只是1~10条会绘制页面 [ convertView仍然是空值 ]

            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.item1, null);
                holder = new ViewHolder();
                holder.textView = (TextView)convertView.findViewById(R.id.text);
                convertView.setTag(holder);
            }
 

当编号为1的条目向上滑动移出屏幕之后[View-1]

编号为11的条目自下进入屏幕,将会直接套用[View-1]

else {
                holder = (ViewHolder)convertView.getTag();
            }


  • 看看代码

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        // 提高刷新的效率,避免卡顿
        // 当子条目容器为空的时候,填充布局式样
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.adapter_circle_msg_item, null);
            holder = new ViewHolder(convertView);
            // setTag的妙用
            // 绑定convertView与ViewHolder贴上Tag
            convertView.setTag(holder);
        } else {
            // setTag的妙用
            // 当convertView非空时候,直接根据Tag拿到绑定的ViewHolder【存放在缓存中的】
            holder = (ViewHolder) convertView.getTag();
        }
        CircleMsgItemInfo info = mInfos.get(position);
        holder.fillViewWithData(info);
        return convertView;
    }

代码解析

  • setTag方法是干什么的?
    setTag给View对象的一个标签,标签可以是任何内容,我们这里把他设置成了一个对象

ViewHolder holder;
...
convertView.setTag(holder);

因为我们先抽象出来成为一个内部类ViewHolder,用了setTag,这个标签就是ViewHolder实例化后对象的一个属性。
我们之后对于ViewHolder实例化的对象holder的操作,都会因为java的引用机制而一直存活并改变convertView的内容,而不是每次都是去new一个,而达到重用的效果。


  • 不使用Tag标签会怎么样呢?

第一种情况:当UI容器没用使用LayoutInflater进行View填充的时候,没必要使用。

第二种情况:当UI容器使用LayoutInflater进行View填充的时候,不使用Tag机制会造成滑动卡顿


  • 使用Tag的必要性?

当ListView中每一个item的布局都不一样的时候,就不需要使用Tag

Tag标志是为了,提交重用的目的拟出的,没有同样的布局就没有意义了


  • Listview滑动UI显示异常的问题

【1】显示顺序异常的问题1-2-3-4-5-6-7-8,滑动之后可能变成2-3-4-5-6-7-8-1?

该问题在我工程中遇到的问题具有特殊性:一共只有8个item条目,且每个布局都不一样

问题处理:取代哦setTag的逻辑

【2】滑动后页面显示异常,A条目的内容可能跟B条目的内容混杂在一起

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            ...
            convertView.setTag(holder);
        } else {

            holder = (ViewHolder) convertView.getTag();
        }
        CircleMsgItemInfo info = mInfos.get(position);
        holder.fillViewWithData(info);
        return convertView;
    }

public void fillViewWithData(CircleMsgItemInfo info) {
            showHeaderBackground(info.getReplyHeadImg());
            name.setText(info.getReplyName());
            if (info.getReplyType().equals("like")) {
                content.setText(R.string.friend_circle_like);
                content.setTextColor(mContext.getResources().getColor(
                        R.color.blue_95));
                TextPaint tp = content.getPaint();
                tp.setFakeBoldText(true);
            } else {
                content.setText(EmojiUtil.formatEmoji(mContext, info.getReplyContent()));
                content.setTextColor(mContext.getResources().getColor(
                        R.color.black));
                TextPaint tp = content.getPaint();
                tp.setFakeBoldText(false);
            }
            time.setText(FriendlyDateFormat.formatTime(info.getReplyTime()));
        }

这是由于Android回收机制导致的,因为设置重用,避免单条View的重新绘制。

fillViewWithData在填充数据的时候,如果没有将item每一个内容都重写一遍的话,遗漏的部分将使用之前item中的内容

事例:

item Old  data : A B C D E

item New date : a    c d e {注意没有 b }

那么显示的效果 : a B c d e








转载于:https://my.oschina.net/u/2273965/blog/368195

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值