2013-03-14 14 views
1

我碰到这个问题好几次,很容易找到一个快速搜索很多类似的问题。有时ListView行布局上的动态更改也会影响其他行,有时它不会。为什么自定义适配器的列表视图有时会表现奇怪?

作为这个问题的解决方案,我通常跟踪列表中的整个项目集,每当我有变化时,我都重置列表中的所有项目。例如:如果我有一个带TextViews和复选框的列表,我必须保留一个布尔值数组,指示每个复选框的状态,并且在我的getView()覆盖函数中重置所有基于该数组的复选框。

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

现在我面临一个问题,我需要一次跟踪多个项目(背景,复选框和文本)在一个非常长的列表中。我想知道是否有任何其他方法来解决这个问题。

回答

1

你这样做是正确的。在Android中,您应该跟踪每个单独列表项的状态。当调用getView时,您可以选择重新使用或为该行创建新视图。通过跟踪项目的状态(文本,选中,背景等),您可以轻松地重置已存在的视图。详细的状态饲养轨道将帮助您确保没有其他行是由一个行的变化

影响你打电话时adapter.notifyDataSetChanged()被重绘是那些在屏幕上(或非常接近,是在屏幕上)唯一的项目。

+0

你有什么参考吗?我怎样才能找出哪些项目重新绘制? AFAIK这是完全随机的,当我做出改变时,哪些项目会“破碎”。 – caiocpricci2 2013-03-14 13:49:56

+0

这是Google的API规范ListView的。我敢打赌,正在发生的事情是,您正在重新使用一个视图,而您并未重置所有状态。因此,一些复选框不应该被检查,反之亦然。当你滚动列表(上下)时,你会看到越来越多的奇怪行为。 – Sababado 2013-03-14 15:54:15

2

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

Android在创建ListView时使用了一种名为View Recycling的技术,因为与使用数据填充视图相比,膨胀视图是一项强化操作。 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; 
} 

有来自适配器类也有许多其他方法,可帮助管理您的列表,并允许你做聪明的事情,杠杆融资的回收,如getItem()用于管理您的基础数据,而getViewType()getViewTypeCount()针对具有多种视图类型的列表,但以上是基本技巧,并且是视图顺利运行所需的最少量。

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

相关问题