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

  • ListView和Adapter的基础知识html

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

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

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

【概要】布局

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

那么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]code

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

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


  • 看看代码
    htm

    @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

相关文章
相关标签/搜索