ListView with Spinner Inside:列表视图的第1项影响其最后一项

时间:2014-04-02 11:09:35

标签: java android android-arrayadapter android-spinner

我有这个奇怪的场景,每当我ListView的第一项中的微调器中选择一个值时,最后ListView's项的微调器value与第一项相同。当ListView项目的总数 5及以上时,仅发生。我评论了代码,只保留了声明,但它仍在发生。这是Android中的错误吗?

澄清:

  • 我的ListView的Scroll Listener为空
  • 我的微调器setOnItemSelectedListener被注释掉了。
  • Android SDK工具版本为22.6.2
  • Android SDK Platform-Tools是19.0.1

    enter image description here

这是适配器代码:

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

    Viewholder v = new Viewholder();
    v.rowView = convertView;
    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if (v.rowView == null) {
        v.rowView = inflater.inflate(R.layout.inner_base_header_cutom, parent, false);
        v.spinner = (Spinner) v.rowView.findViewById(R.id.spinner1);
        v.rowView.setTag(v);
    } else {
        v = (Viewholder) v.rowView.getTag();
    }

    return v.rowView;
}

ViewHolder:

class Viewholder{
    View rowView;
    TextView itemPID;
    TextView itemPrice;
    TextView itemItemId;
    Spinner spinner;
    TextView subtotal;
}

XML:

<Spinner
    android:id="@+id/spinner1"
    android:layout_width="100dip"
    android:layout_height="wrap_content"
    android:layout_margin="20dip"
    android:entries="@array/quanitiy"
    android:layout_alignTop="@+id/itemPrice"
    android:layout_toRightOf="@+id/imageDisplay" />

阵列:

   <string-array name="quanitiy">
        <item>Quantity</item>
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>4</item>
        <item>5</item>
        <item>6</item>
        <item>7</item>
        <item>8</item>
        <item>9</item>
        <item>10</item>
    </string-array>

更新 我注释掉了OnItemClickListner的代码。我更新了上面的代码,仍然存在问题。唯一剩下的是声明。

情境: 如果我在1的微调器[索引0]的第一项处选择ListView,则ListView微调器的最后一项也会1而不进行交互。当列表视图的项目向下到最后一部分时,我发现它们都是相同的。我评论了代码并保留了声明。

1 个答案:

答案 0 :(得分:4)

好的,现在我明白了。谢谢你的澄清。你的问题来自于被回收的观点。您应该查看this post以更好地了解回收。

简答

基本上,当您使用convertView中的getView()时,您正在重复使用不再可见的项目的视图。这就是为什么它的字段(包括微调器,价格的textview)已经设置为某种东西,你应该在getView()中自己设置它们。为这些文本字段和微调器提供的值应取决于指定position处的项目。

详细答案

以下是回收的内容(图片摘自前面提到的帖子):

recycling process

您的问题

当您滚动显示一个新项目(比如项目8,如图片)时,用于显示它的视图与第一个项目(项目1)的视图相同。因此,当您在第一个项目的微调器上选择某个内容,然后向下滚动时,您将看到最后一个项目的更改,因为您的getView不会更改用于项目的视图的值1(但它应该更新它们!)。

注意:您案例中第一项和最后一项的对应完全是偶然的。通常情况下,视图会重复用于2个项目,这些项目大致由一个屏幕高度中的项目数分隔,如图所示。

您的getView

代码中的内联说明
Viewholder v = new Viewholder(); // why create a new one, while you might reuse the former one?

// here rowView becomes the same as the former item's view, with all the former values
v.rowView = convertView; 

// you don't need this here but only in the case rowView is null, should be in your 'if'
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

if (v.rowView == null) {
    v.rowView = inflater.inflate(R.layout.inner_base_header_cutom, parent,false);
    v.spinner = (Spinner) v.rowView.findViewById(R.id.spinner1);
    v.rowView.setTag(v);
    // here you inflated a new view (nothing reused) 
    // but you didn't initialize anything
} else {
    v = (Viewholder) v.rowView.getTag();
    // here you're reusing the former View and ViewHolder 
    // and you don't change the values
}

解决方案

您不应该让这些项目按照自己的意愿行事,但是您应该告诉他们在getView()中初始化项目视图的内容时要显示的内容。对于上图,这意味着您需要将之前的项目1更改为第8项

您应该保持适配器中每个项目的状态。您可能有一个支持列表或某些内容,以显示ListView中不同的元素,具体取决于position,对吗? 然后你应该使用一个类似的列表(或相同的)来存储在微调器中选择的值,由文本字段显示的价格等值。这些应该可能对应于当前列表中的项目的字段,所以你可能已经有一些地方可以存放它们。

另一方面,当您在convertView中重复使用getView()时,请确保使用{的项目的正确值初始化微调器(以及文本字段以及此项目视图中的所有内容) {1}}。

position

的解决方案代码(模板)
getView