一.notisfyDataChanged
- 在编写上面的界面时,因为只能选择一种托保方式,所以希望在某个checkbox被选中时,其他的checkbox可以自动取消选中,而这又是ListView中的两个item,这说明其中一个item的操作会影响另一个item的状态。
- 后来发现可以用notisfyDataChanged解决这个问题,每次某个checkbox被改变都通知adapter取消另一个checkbox的选中。
- 根据原码可以发现notisfyDataChanged其实是重绘了listview的界面
requestLayout()重绘了界面
类似的还有setAdapter,但它还和原有观察者解除了绑定,这使得它丢失了原有的位置信息和数据信息
public void setAdapter(ListAdapter adapter) {
// 与原有观察者解绑定
if (mAdapter != null && mDataSetObserver != null) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
}
resetList();
mRecycler.clear();
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
mOldSelectedPosition = INVALID_POSITION;
mOldSelectedRowId = INVALID_ROW_ID;
// AbsListView#setAdapter will update choice mode states.
super.setAdapter(adapter);
if (mAdapter != null) {
mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();
mOldItemCount = mItemCount;
mItemCount = mAdapter.getCount();
checkFocus();
// 重新绑定新的数据集观察者
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());
int position;
if (mStackFromBottom) {
position = lookForSelectablePosition(mItemCount - 1, false);
} else {
position = lookForSelectablePosition(0, true);
}
setSelectedPositionInt(position);
setNextSelectedPositionInt(position);
if (mItemCount == 0) {
// Nothing selected
checkSelectionChanged();
}
} else {
mAreAllItemsSelectable = true;
checkFocus();
// Nothing selected
checkSelectionChanged();
}
requestLayout();
}
二.ViewHolder
- 最开始写listview的apapter时,getView方法中每次都会inflate出一个新的view,如果item很多,滚动起来就会创建很多的view,十分的浪费资源。
- 但其实用converView.setTag来保存这些view,像一个缓冲池一样,免去了很多加载和创建
- 而ViewHolder可以保存view中的控件,替代了findViewById()