在列表视图中重绘单行

时间:2010-11-02 08:26:23

标签: android listview view android-arrayadapter redraw

是否可以在ListView中重绘一行?我有ListViewLinearLayout s。我听取偏好更改,有时我需要在单行的View内更改一个LinearLayout。有没有办法让它重新绘制该行而不调用listview.notifyDatasetChanged()

我尝试在视图上调用view.invalidate()(在LinearLayout内),但它没有重绘行。

4 个答案:

答案 0 :(得分:105)

作为Romain Guy explained a while回到Google I/O session期间,仅在列表视图中更新一个视图的最有效方法如下(此更新整个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()将重建整个列表并最终调用{{ 1}}对于每个显示的项目,getview()也会影响一堆。

最后一件事,如果他只需要更改行视图的子项而不是像invalidateViews()这样的整行,那么也可以获得额外的性能。在这种情况下,以下代码可以替换getView(例如更改list.getAdapter().getView(i, view, list);文本):

TextView

在我们信任的代码中。

答案 1 :(得分:6)

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

假设您正在更新行中的“position”位置。 if避免了怪异的重绘内容,就像文字跳舞一样 更新不在屏幕中的行。

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

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            listView.invalidateViews();
                        }
                    });
            }

答案 2 :(得分:3)

Romain Guy在“Google IO 2010 ListView的世界”中回答了这个问题 在提出此问题的确切时间的视频:http://www.youtube.com/watch?feature=player_detailpage&v=wDBM6wVEO70#t=3149s

根据Romain Guy的说法,这应该有效,我认为我们可以信任他。

您的视图未重绘的原因有点神秘。 也许尝试禁用listView中可用的所有缓存选项

setAnimationCacheEnabled(false);
setScrollingCacheEnabled(false);
setChildrenDrawingCacheEnabled(false);
setChildrenDrawnWithCacheEnabled(false);

答案 3 :(得分:0)

在要更新的行上添加一些标记。 如果要重绘特定视图或行,请执行

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

然后

View v = lv.findViewWithTag(tagobject);

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