`listView.invalidate()` 和 `adapter.notifyDataHasChanged()` 之间有区别吗?
Is there a difference between `listView.invalidate()` and `adapter.notifyDataHasChanged()`?
我有一个物品清单。
我想长按删除一个项目。
我看到了这个 post,它对我有用。
出于好奇,我想知道为什么其他解决方案对我不起作用:
溶胶 1
我将列表注册到上下文菜单:
registerForContextMenu(listView);
然后:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
if (v.getId()==R.id.comments_list) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.phone_list_contextual_menu, menu);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()) {
case R.id.edit: {
return true;
}
case R.id.delete: {
comments.remove(info.id);
listView.invalidate();
return true;
}
default: {
return super.onContextItemSelected(item);
}
}
}
和
有区别吗
listView.invalidate()
和 adapter.notifyDataHasChanged()
?在通话主题旁边?
我缺少什么才能使删除工作正常进行?
溶胶 2
listView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int position = (int) v.getTag();
comments.remove(position);
listView.invalidate();
return true;
}
});
而不是
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
comments.remove(pos);
//listView.invalidate();
arrayAdapter.notifyDataSetChanged();
return true;
}
});
我知道 setOnItemLongClickListener
比 setOnLongClickListener
更适合我的需要,但是
为什么这对我不起作用?
不同之处在于 invalidate
会导致您在列表中的所有视图都被废弃并重新绘制。请注意,我说的是视图,所以这就是您在屏幕上实际看到的内容(例如,您可以在屏幕上有 3 个视图,但列表中有 20 个项目)
另一方面,notifyDataHasChanged
告诉适配器内容已更改,适配器需要重新运行 其对内容的方法以刷新列表。
您几乎总是想使用 notifyDataHasChanged
但这取决于您要完成的具体目标。
希望对您有所帮助。
Is there a difference between
listView.invalidate() and adapter.notifyDataHasChanged() ? beside the subject of the call?
据我了解,adapter.notifyDataHasChanged() 会做 listView.invalidate() 的事情,而且还会做更多。这意味着它还将包括项目数量的变化,并可能将数据变化通知其他观察者。相关代码在这里:
http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/widget/AdapterView.java#798
这是针对 notifyDataHasChanged() 的,如您所见,mItemCount 已更新为新值。这意味着如果您向 arrayadapter 添加更多项,则 invalidate 或更好的 invalidateViews 将不会显示它们,至少在列表末尾是这样。我注意到的一件事是上面的代码没有无效调用 - 可能是由其他一些方法调用的。
下面是 invalidateViews 的源代码(我认为这比 Invalidate 更合适):
http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#5078
它没有更新项目数量的代码。
如果您搜索 android 来源的源代码,您会发现调用 invalidateViews 的情况很少,其中一些地方是优化黑客。
我有一个物品清单。
我想长按删除一个项目。
我看到了这个 post,它对我有用。
出于好奇,我想知道为什么其他解决方案对我不起作用:
溶胶 1
我将列表注册到上下文菜单:
registerForContextMenu(listView);
然后:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
if (v.getId()==R.id.comments_list) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.phone_list_contextual_menu, menu);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()) {
case R.id.edit: {
return true;
}
case R.id.delete: {
comments.remove(info.id);
listView.invalidate();
return true;
}
default: {
return super.onContextItemSelected(item);
}
}
}
和
有区别吗listView.invalidate()
和 adapter.notifyDataHasChanged()
?在通话主题旁边?
我缺少什么才能使删除工作正常进行?
溶胶 2
listView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int position = (int) v.getTag();
comments.remove(position);
listView.invalidate();
return true;
}
});
而不是
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
comments.remove(pos);
//listView.invalidate();
arrayAdapter.notifyDataSetChanged();
return true;
}
});
我知道 setOnItemLongClickListener
比 setOnLongClickListener
更适合我的需要,但是
为什么这对我不起作用?
不同之处在于 invalidate
会导致您在列表中的所有视图都被废弃并重新绘制。请注意,我说的是视图,所以这就是您在屏幕上实际看到的内容(例如,您可以在屏幕上有 3 个视图,但列表中有 20 个项目)
notifyDataHasChanged
告诉适配器内容已更改,适配器需要重新运行 其对内容的方法以刷新列表。
您几乎总是想使用 notifyDataHasChanged
但这取决于您要完成的具体目标。
希望对您有所帮助。
Is there a difference between
listView.invalidate() and adapter.notifyDataHasChanged() ? beside the subject of the call?
据我了解,adapter.notifyDataHasChanged() 会做 listView.invalidate() 的事情,而且还会做更多。这意味着它还将包括项目数量的变化,并可能将数据变化通知其他观察者。相关代码在这里:
http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/widget/AdapterView.java#798
这是针对 notifyDataHasChanged() 的,如您所见,mItemCount 已更新为新值。这意味着如果您向 arrayadapter 添加更多项,则 invalidate 或更好的 invalidateViews 将不会显示它们,至少在列表末尾是这样。我注意到的一件事是上面的代码没有无效调用 - 可能是由其他一些方法调用的。
下面是 invalidateViews 的源代码(我认为这比 Invalidate 更合适):
http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#5078
它没有更新项目数量的代码。
如果您搜索 android 来源的源代码,您会发现调用 invalidateViews 的情况很少,其中一些地方是优化黑客。