是否可以在 a 中重绘单行ListView
?我有一个ListView
带有LinearLayout
s 的行。我听取偏好更改,有时我只需要更改单行中的一个View
。LinearLayout
有没有办法让它在不调用的情况下重绘该行listview.notifyDatasetChanged()
?
我尝试在视图(内部)上调用 view.invalidate() ,LinearLayout
但它不会重绘该行。
是否可以在 a 中重绘单行ListView
?我有一个ListView
带有LinearLayout
s 的行。我听取偏好更改,有时我只需要更改单行中的一个View
。LinearLayout
有没有办法让它在不调用的情况下重绘该行listview.notifyDatasetChanged()
?
我尝试在视图(内部)上调用 view.invalidate() ,LinearLayout
但它不会重绘该行。
正如 Romain Guy 不久前在Google I/O 会议期间所解释的那样,仅更新列表视图中的一个视图的最有效方法如下(这个更新整个数据):View
ListView list = getListView();
int start = list.getFirstVisiblePosition();
for(int i=start, j=list.getLastVisiblePosition();i<=j;i++)
if(target==list.getItemAtPosition(i)){
View view = list.getChildAt(i-start);
list.getAdapter().getView(i, view, list);
break;
}
假设target
是适配器的一项。
此代码检索ListView
,然后浏览当前显示的视图,将target
您要查找的项目与每个显示的视图项目进行比较,如果您的目标在其中,则获取封闭视图并getView()
在该视图上执行适配器以刷新显示。
作为旁注invalidate()
并不像某些人期望的那样工作并且不会像这样getView()
做那样刷新视图,notifyDataSetChanged()
将重建整个列表并最终调用getview()
每个显示的项目并且invalidateViews()
还会影响一堆。
最后一件事,如果他只需要更改行视图的子视图而不是像getView
这样的整行,也可以获得额外的性能。在这种情况下,以下代码可以替换list.getAdapter().getView(i, view, list);
(更改TextView
文本的示例):
((TextView)view.findViewById(R.id.myid)).setText("some new text");
在我们信任的代码中。
对view.invalidate()
我不起作用。但这就像一个魅力:
假设您正在更新position
行中的位置“”。避免奇怪的if
重绘内容,例如当您更新不在屏幕中的行时文本跳舞。
if (position >= listView.getFirstVisiblePosition()
&& position <= listView.getLastVisiblePosition()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
listView.invalidateViews();
}
});
}
Romain Guy 在“Google IO 2010 The world of ListView”视频中回答了这个问题,就在这个问题被问到的确切时间:http ://www.youtube.com/watch?feature=player_detailpage&v=wDBM6wVEO70#t=3149s
所以根据 Romain Guy 的说法,这应该可行,我认为我们可以信任他。
你的视图没有重绘的原因有点神秘。也许尝试禁用 listView 中可用的所有缓存选项
setAnimationCacheEnabled(false);
setScrollingCacheEnabled(false);
setChildrenDrawingCacheEnabled(false);
setChildrenDrawnWithCacheEnabled(false);
在要更新的行上放置一些标签。当您想重绘该特定视图或行时,请执行
ListView lv = (ListView)findViewById(....)
进而
View v = lv.findViewWithTag(tagobject);
然后你对视图做任何你想做的事情。