自定义 listview 适配器 getView 方法被多次调用,且顺序不一致

我有一个自定义列表适配器:

class ResultsListAdapter extends ArrayAdapter<RecordItem> {

在重写的“ getView”方法中,我打印一个文件来检查位置以及它是否是 ConvertView:

    @Override
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("getView " + position + " " + convertView);

这样做的输出(当列表第一次显示时,还没有用户输入)

04-11 16:24:05.860: INFO/System.out(681): getView 0 null
04-11 16:24:29.020: INFO/System.out(681): getView 1 android.widget.RelativeLayout@43d415d8
04-11 16:25:48.070: INFO/System.out(681): getView 2 android.widget.RelativeLayout@43d415d8
04-11 16:25:49.110: INFO/System.out(681): getView 3 android.widget.RelativeLayout@43d415d8
04-11 16:25:49.710: INFO/System.out(681): getView 0 android.widget.RelativeLayout@43d415d8
04-11 16:25:50.251: INFO/System.out(681): getView 1 null
04-11 16:26:01.300: INFO/System.out(681): getView 2 null
04-11 16:26:02.020: INFO/System.out(681): getView 3 null
04-11 16:28:28.091: INFO/System.out(681): getView 0 null
04-11 16:37:46.180: INFO/System.out(681): getView 1 android.widget.RelativeLayout@43cff8f0
04-11 16:37:47.091: INFO/System.out(681): getView 2 android.widget.RelativeLayout@43cff8f0
04-11 16:37:47.730: INFO/System.out(681): getView 3 android.widget.RelativeLayout@43cff8f0

AFAIK,虽然我发现它没有明确的说明,但是 getView ()只对可见的行调用。由于我的应用程序从四个可见行开始,至少从0到3循环的位置数字是有意义的。但剩下的就是一团糟:

  • 为什么每一行都要调用三次 getview?
  • 当我还没有滚动时,这些转换视图是从哪里来的?

我做了一些研究,没有得到一个好的答案,我确实注意到人们把这个问题与布局问题联系起来。以防万一,下面是包含列表的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical" >


<TextView android:id="@+id/pageDetails"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />


<ListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false" />


</LinearLayout>

以及每一行的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="108dp"
android:padding="4dp">


<ImageView
android:id="@+id/thumb"
android:layout_width="120dp"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginRight="8dp"
android:src="@drawable/loading" />


<TextView
android:id="@+id/price"
android:layout_width="wrap_content"
android:layout_height="18dp"
android:layout_toRightOf="@id/thumb"
android:layout_alignParentBottom="true"
android:singleLine="true" />


<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="18dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:paddingRight="4dp"
android:singleLine="true" />


<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="17dp"
android:layout_toRightOf="@id/thumb"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingRight="4dp"
android:layout_alignWithParentIfMissing="true"
android:gravity="center" />


</RelativeLayout>

打扰了

84502 次浏览

“为什么每行都要调用三次 getview?” 因为 getView 是在您在 listview 上滚动时调用的,而且当您的列表视图的位置发生更改时,它会被调用!

这不是一个问题,完全不能保证 getView()的调用顺序,也不能保证调用次数。在你的特殊情况下,你正在做最坏的事情可能与一个 ListView给它一个 height=wrap_content。这迫使 ListView在布局时从适配器中测量几个子级,以了解它应该有多大。这是什么提供了 ListViewconvertViews你看到传递到 getView()甚至在你滚动之前。

在列表视图的 layout_height属性上尝试使用 match_parent。它将防止如此频繁地调用 getView()

我也有同样的问题。如果高度设置为 fill _ father,那么每行“通常”会有2个调用。但是,如果我将 ListView 的高度设置为精确值,比如说300dp,那么每行就会得到一个 GetView 调用。

因此,在我看来,唯一的方法是首先确定屏幕的高度,然后通过编程将 listvilew 的高度设置为该值。我不喜欢这样。我希望有更好的办法。

我不能回答你的“为什么”的问题,但我肯定有一个令人恼火的“ 重复的 ListView 项”问题的解决方案(如果你有项目在您的收藏超过屏幕高度)。

正如上面提到的,将 ListVew标签的 布局高度属性保留为 家长

至于 getView ()函数,解决方案是使用名为 视图持有人静态类。看看 这个的例子。它成功地完成了在 Array 或 ArrayCollection 中添加所有项的任务。

希望这对朋友有帮助! !

最好的问候, Siddhant

当我把 laywidth 和 layheight 都改为 Match _ father时(仅仅改变 layoheight 没有帮助) ,我摆脱了这个问题。


有用的提示 注意你是否有嵌套的项目。你得把最高的那个改成 Match _ father。希望能帮到别人。

问题: 为什么 Adapter 多次调用 getView () ? 答: 当 Listview 在滚动时呈现的是刷新它的视图,下一个视图是 哪个适配器需要通过调用 getView ()来获取视图。

问题: 为什么当 listview 的高度和宽度设置为 fill _ father 时,调用次数会减少? 答: 因为充气机有固定大小的屏幕区域列表计算一次 将视图呈现在屏幕上。

希望能解决你的疑问。

我在 AutoCompleteTextView 中遇到了同样的问题。我和这个问题斗争了两天,直到我来到这里,你告诉我解决办法。

如果我写下 drop DownHeight = “ match _ father”,问题就解决了。现在这个问题与 UI 有关(当你有一个条目时,下拉框太大了) ,但是多个调用的问题(更重要的是)已经解决了。

谢谢!

对于那些仍然(在将 ListViewheight设置为 match_parent之后)被卡住的人(就像我一样) :

您还必须将父布局的 height设置为 match_parent

看下面的例子。 LinearLayout是这里的父代:

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/something" />


<ListView
android:id="@+id/friendsList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

这可能来晚了,但如果你使用 layout_weight记得总是设置 layout_width="0dp"

我做了这个解决方案,也许不是最好的,但是工作..。

//initialize control string
private String control_input = " ";

然后 =

@Override
public View getView(int position, View convertView, ViewGroup parent) {


View gridview = convertView;


// change input_array for the array you use
if (!control_input.equals(input_array[position])) {
control_input = input_array[position];


//do your magic


}


return gridview;
}

希望能有帮助!

我也遇到过类似的问题,在进行下一步操作之前,getView在索引0(i = 0)上被调用了三次。在我的例子中,我想要计算项目的总价格,但是在这个问题中,第一个项目被计算为 x3。 为了解决这个问题,我创建了一个 int indexFix = 0;,并在 i发生变化时增加它

    if (indexFix == i)
{
Total += itemTotal;
indexFix++;
}

我尝试了以上的解决方案,但似乎没有一个在我的情况下工作。如果你不能修复它只是控制在 getView做什么