BaseAdapter notifyDataSetChanged()

 

BaseAdapter 有一个方法:notifyDataSetChanged()

用途:在adapter的数据发生变化以后通知UI主线程根据新的数据重新画图。

 

从名字看,这个是一个notify,感觉就是发出通知了,但是通知什么时候被接受什么时候处理完成是不定的。

事实上其实也是这样的。

 

这个方法的实现:

public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }

再往下,会调用一个observer.onChanged();

 

那么,mDataSetObservable是什么呢?

 

我理解是

public void registerDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.registerObserver(observer);
    }

设置进来的,这个应该是跟view相关的,比如说看GridView的setAdapter方法里面有:

mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);

 

AdapterDataSetObserver类里面有onChanged方法的实现

里面有调用一个requestLayout();

 

View的requestLayout()会调用mParent.requestLayout();

跑到ViewRoot的

 public void requestLayout() {
        checkThread();
        mLayoutRequested = true;
        scheduleTraversals();
    }

 

scheduleTraversals的实现

public void scheduleTraversals() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            sendEmptyMessage(DO_TRAVERSAL);
        }
    }

 

所以,其实notifyDataSetChanged是发送了一个message给主线程,告诉它,要重画了啊。

 

之所以看这个,其实跟之前bitmap recycle的时间点的问题是相关联的。

例如有一个grid view,它跟一个adapter捆绑,adapter用到的数据包括现实在grid每个item的bitmap,在数据刷新的之后,调用notifyDataSetChanged通知UI重画,那旧的bitmap要在什么时候recycle比较合适合理?

 

近来觉得message queue真的是很好用的东西,这里,recycle不要直接调用【直接调用的话,没有办法保证notifyDataSetChanged的通知什么时候被处理完,万一没处理完,recycle掉了图片,又想找图片画画面的时候就麻烦了】,而是在notifyDataSetChanged后面再丢message/runable到queue里面,让UI主线程recycle旧图片。这样就保证了只有UI上bitmap已经设置为新的了,旧的才会被recycle掉。

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在 `BaseAdapter` 的 `getView` 方法中,`setSelected` 方法设置选中项的状态在 `notifyDataSetChanged` 后可能不起作用,这是因为 `getView` 方法会被调用来重新绘制列表中的所有项,而 `setSelected` 方法只会在首次绘制时起作用。 为了解决这个问题,你可以在适配器中添加一个额外的变量来记录选中项的位置,并在 `getView` 方法中根据该变量来设置选中项的状态。当选中项发生改变时,更新该变量并调用 `notifyDataSetChanged` 方法来刷新列表。 下面是一个示例: ```java public class MyAdapter extends BaseAdapter { private int selectedPosition = -1; // 记录选中项的位置 // ... @Override public View getView(int position, View convertView, ViewGroup parent) { View itemView = convertView; if (itemView == null) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); itemView = inflater.inflate(R.layout.item_layout, parent, false); } // 设置选中项的状态 if (position == selectedPosition) { itemView.setSelected(true); } else { itemView.setSelected(false); } // ... return itemView; } // 设置选中项的方法 public void setSelectedPosition(int position) { selectedPosition = position; notifyDataSetChanged(); // 刷新列表 } } ``` 在上述示例中,通过 `setSelectedPosition` 方法来设置选中项的位置,然后调用 `notifyDataSetChanged` 方法来刷新列表。在 `getView` 方法中根据选中项的位置来设置选中项的状态。这样可以保证在列表刷新后,选中项的状态仍然正确显示。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值