40

是否可以在 a 中重绘单行ListView?我有一个ListView带有LinearLayouts 的行。我听取偏好更改,有时我只需要更改单行中的一个ViewLinearLayout有没有办法让它在不调用的情况下重绘该行listview.notifyDatasetChanged()

我尝试在视图(内部)上调用 view.invalidate() ,LinearLayout但它不会重绘该行。

4

4 回答 4

108

正如 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");

在我们信任的代码中。

于 2012-04-03T05:34:38.677 回答
6

view.invalidate()我不起作用。但这就像一个魅力:

假设您正在更新position行中的位置“”。避免奇怪的if重绘内容,例如当您更新不在屏幕中的行时文本跳舞。

            if (position >= listView.getFirstVisiblePosition()
                && position <= listView.getLastVisiblePosition()) {

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            listView.invalidateViews();
                        }
                    });
            }
于 2011-10-05T23:17:50.783 回答
3

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);
于 2011-10-22T14:15:53.173 回答
0

在要更新的行上放置一些标签。当您想重绘该特定视图或行时,请执行

ListView lv = (ListView)findViewById(....)

进而

View v = lv.findViewWithTag(tagobject);

然后你对视图做任何你想做的事情。

于 2011-03-14T13:07:26.737 回答