当前位置: 首页 > 知识库问答 >
问题:

为什么带有自定义适配器的ListView有时表现得很奇怪?

洪梓
2023-03-14
  • 复选框问题
  • 编辑文本问题
  • 按钮问题

我已经多次遇到这个问题,通过快速搜索很容易找到许多类似的问题。有时列表视图行布局的动态更改也会影响其他行,有时不会。

作为这个问题的解决方案,我通常会跟踪列表中的全部项目,每次我有一个变化,我都会重置列表中的所有项目。

例如:如果我有一个包含文本视图和复选框的列表,我必须保留一个布尔数组,指示每个复选框的状态,在我的getView()覆盖中,我会根据该数组重置所有复选框。

这是预期的吗?我可以找到几个关于这个问题的问题,所有的解决方案似乎都和我的类似。

现在我面临一个问题,我需要同时跟踪一个很长的列表中的几个项目(背景、复选框和文本)。我想知道是否有其他方法可以解决这个问题。

共有2个答案

萧凡
2023-03-14

你做得对。在Android系统中,你应该跟踪每个列表项的状态。调用getView时,您可以选择重新使用或为行创建新视图。通过跟踪项目的状态(文本、已选中、背景等),可以轻松重置已存在的视图。跟踪详细状态将有助于确保其他行不受一行更改的影响

当你调用适配器时。NOTIFYDATASETCHANGE()重画的项目只有屏幕上的项目(或非常接近屏幕的项目)。

公冶鸣
2023-03-14

这是Android中ListView的预期行为。使用基础数据填充列表中的视图的方法是正确的。

Android在创建ListView时使用了一种称为“视图回收”的技术,因为与填充数据相比,膨胀视图是一项密集的操作。Android(在程序员的帮助下)只创建用户在屏幕上看到的视图,从而将通胀保持在最低水平。当用户向上滚动列表时,离开屏幕的视图将被放置在一个池中,供即将显示的新项目重用。此池中的视图作为第二个参数传递给getView。此视图将保留从列表中弹出时的确切状态,因此由getView方法清除任何旧数据的状态,并根据基础数据的新状态重新填充它。以下是getView()的实现应该具有的结构示例:

@Override
public View getView (int position, View convertView, ViewGroup parent)
{
    //The programmer has two responsibilities in this method.

    //The first is to inflate the view, if it hasn't been
    //convertView will contain a view from the aforementioned pool, 
    //    but when first creating the list, the pool is empty and convertView will be null
    if(convertView == null)
    {
        //If convertView is null, inflate it, something like this....
        convertView = layoutInflator.inflate(R.layout.mylistview, null);
    } 

    //If convertView was not null, it has previously been inflated by this method

    //Now, you can use the position argument to find this view's data and populate it
    //It is important in this step to reset the entire state of the view.
    //If the view that was popped off the list had a checked CheckBox, 
    //    it will still be selected, EditTexts will not be cleared, etc.

    //Finally, once that configuration is done, return convertView
    return convertView;
}

Adapter类中还有许多其他方法可以帮助管理列表,并允许您利用视图循环进行巧妙的操作,例如用于管理基础数据的getItem(),以及用于具有多种视图类型的列表的getViewType()getViewTypeCount(),但以上是基本技巧,也是视图顺利运行所需的最低限度。

听起来你是在正确的轨道上,我希望这有助于回答你的一些问题。如果有什么不清楚的,请告诉我你想要更多的信息。

 类似资料:
  • 我正在尝试将ListView与fragmnet中的自定义适配器(baseAdapter)一起使用。 当我直接在MainActivity中使用此代码时,一切正常,但当我在片段中使用此代码时,它没有崩溃,但它没有显示任何内容,它只是一个空白片段。另外,当我尝试使用简单的arrayAdapter在片段中绑定一个textView时,它工作得很好,所以我认为问题将出现在我的自定义适配器中。 为什么不显示Li

  • 我正在尝试在ndroid ListView上应用搜索,但它对我不起作用,这里是我尝试的代码。 下面是Users类

  • 问题内容: 我有一个使用自定义适配器的ListView,如下所示: 布局非常简单,因此除非有人认为它们相关,否则我不会发布它们。 问题是某些CheckBoxes没有响应。似乎是第一次显示布局时可见的内容。您必须向下滚动才能正常工作的任何内容。 任何指针表示赞赏。 问题答案: 答案中的代码有效,但效率很低(实际上,您可以看到它,只需滚动并检查即可看到垃圾收集器正在工作)。下面是一种改进的回收视图的方

  • 我正试图为我的设置一个自定义,如下所示 在调试中,应用程序正在输入

  • 我有一个图像压缩应用程序,现在有两个不同版本的内存分配系统。在最初的一个例子中,malloc无处不在,在第二个例子中,我实现了一个简单的池分配器,它只分配大块内存,并将部分内存返回给myalloc()调用。 我们注意到,使用malloc时会产生巨大的内存开销:在内存使用量最大的时候,malloc()代码对于1920x1080x16bpp映像需要大约170 MB的内存,而池分配器只分配48 MB,其

  • 问题内容: 这是我遵循的使用自定义Listview适配器的教程。我遇到的问题是,当我尝试清除适配器时,应用程序崩溃并抛出 更新的代码: 问题答案: 环顾四周,似乎是使用数组初始化适配器。请参阅带有ArrayAdapter.remove的UnsupportedOperationException和无法在ListView中修改ArrayAdapter:UnsupportedOperationExcep