CursorAdapter在每个项目上调用bindView

时间:2010-10-04 22:13:05

标签: android cursor listadapter

我正在使用DeskClock中的一些代码,发现当我尝试修改CursorAdapter时,为每个项目调用了newView。 (我实际上想添加一个分隔符,看起来分别添加分隔符比将它们添加到单个listView更好)

如果我有3个项目,我会收到以下行为:

 newView - called with item: 0
  bindView - called with item: 0
  bindView - called with item: 1
  bindView - called with item: 2
  bindView - called with item: 0
 newView - called with item: 1
  bindView - called with item: 1
 newView - called with item: 2
  bindView - called with item: 2
 newView - called with item: 0
  bindView - called with item: 0
  bindView - called with item: 1
  bindView - called with item: 2

我希望每个游标项都能调用一次newView / bindView。但是,情况似乎并非如此。这对我来说是个问题,因为我想根据游标数据选择合适的视图,但是因为在newView之前调用bindView不起作用。

这是一些奇怪的回收行为(或以某种方式正常/预期)?或者有什么东西被代码破坏了(我删除了除ListView之外的所有内容,它仍在执行此操作)?我不太确定你为什么要尝试绑定尚未创建的视图,以及为什么newView会在第一个项目上被调用两次。

谢谢!

不过,如果有人有一种简单的方法可以为ListView添加分频器,我很​​乐意知道。我打算尝试深入了解联系人示例,看看他们是否在那里做到了。


顺便说一下,如果有人想知道MergeAdapter是不是很整洁并尝试(我会在其他情况下使用它)。但是,我最后编写了一个处理多个视图的适配器。它计算每个项目的类型(很小),将其存储在地图中,在创建适配器时初始化它,并在notifyDataSetChanged中更新它。

然后你只需要让getViewTypeCount()返回可能的视图数。并且getItemViewType从地图返回类型(基于0,因此0-getViewTypeCount())。如果你可以从你不需要地图的位置计算你的类型,但是不能在飞行中这样做,所以我只需要在需要时预先/重新计算。

3 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,在我的光标中每个条目多次调用bindView(确切地说是3)。 我找到的修复方法是将布局切换为相对布局,如下所示:

  <?xml version="1.0" encoding="utf-8"?>
  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    >
     <ListView
       android:id="@android:id/list"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:background="#666666"
       android:layout_weight="1"
       android:drawSelectorOnTop="false"
       android:layout_alignParentTop="true"
       />
    <TextView android:id="@android:id/empty"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:background="@drawable/shape_gradient_2"
               android:text="No Evidence Available"               
               android:padding="10dp"
               android:layout_below="@android:id/list"

               />
  </RelativeLayout>

以前我一直在使用LinearLayout而无法让它工作。我使用LinearLayout每行调用一次bindView的唯一方法是在ListView上设置一个固定的高度。由于几乎任何LinearLayout都可以使用RelativeLayout重新创建,因此您应该只需切换两个,然后告诉ui放置每个元素的位置。 我仍然不明白为什么我们必须这样做,我花了一天的时间来解决问题,但至少现在它已经解决了。我真的很惊讶更多人没有看到这个问题。

答案 1 :(得分:2)

  

这对我来说是一个问题,因为我想根据游标数据选择合适的视图,但是因为在newView不能工作之前可以调用bindView。

您是否覆盖了getViewTypeCount()getItemViewType()

  

这是一些奇怪的回收行为(或以某种方式正常/预期)?或者是否有一些代码被破坏了(除了ListView之外我删除了所有内容,它仍在执行此操作)?

肯定有点奇怪。

  不过,如果有人有一种简单的方法可以为ListView添加分频器,我很​​乐意知道。我打算尝试深入了解联系人示例,看看他们是否在那里做到了。

最后,如何将分频器添加到ListViews几乎完全取决于何时出现分频器的标准。无法提供一刀切的解决方案。

例如,我的MergeAdapter可以用于分隔符,其中分隔符之间的每个块可以包含在它自己的ListAdapter中。这对某些场景非常有用。但是,假设分隔符实际上是由数据库查询中的列(例如,类别)确定的。每个类别运行大量子查询以将每个Cursor包装在自己的SimpleCursorAdapter中以供MergeAdapter使用,这将非常痛苦。最好是创建一种不同类型的包装Adapter,它可以根据检测到的类别值的变化动态插入标题。我手边没有这样的Adapter样本,虽然它在我的18,000项待办事项清单上......

答案 2 :(得分:0)

使用光标的getPosition方法查看项目位置。

cursor.getPosition();