ListView控件与微调内部:列表视图的第一个项目影响它的最后一个项目项目、它的、第一个、视图

2023-09-14 00:01:31 作者:恋你不是罪

我有这个奇怪的场景,每一次我的从的ListView 的第一个项目,在的微调选择值最后 ListView的项目的微调值是一样的第一个项目。这将只发生时的ListView项目总数的 5及以上。我注释掉codeS和留住只是宣言和它仍然发生。这是Android的一个错误?

I had this weird scenario where every time I select a value from the spinner in the ListView's 1st Item, the last ListView'sitem its spinner value is the same as the first item. This will only happen when the total number of ListView items is 5 and above. I commented out the codes and retain just the declarations and it's still happening. Is this a bug in Android?

澄清:

在我的ListView的滚动监听器是空 在我的飞旋的 setOnItemSelectedListener 被注释掉了。 在Android的SDK工具版本为22.6.2

Android的SDK平台工具为19.0.1 My ListView's Scroll Listener is empty My spinner's setOnItemSelectedListener is commented out. Android SDK Tool version is 22.6.2

Android SDK Platform-Tools is 19.0.1

下面的适配器code:

Here's the adapter code:

@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:

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>

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

UPDATE I commented out the code for OnItemClickListner. I updated the code above, still the problem exists. The only thing left is the declarations.

方案: 如果我选择 1 在微调的第一个项目的ListView 的最后一个项目的[索引0] 的ListView 的微调也 1 变得没有互动。当下来ListView的项目,直到最后一部分,这就是我发现它们都是一样的。我注释掉C $ CS的$,只是保留了声明。

Scenario: If I select 1 at the first item of the spinner [index 0] of the ListView, the last item of ListView's spinner gets also 1 without interaction. When down the listview's items until the last part, that's where I found out that they are both the same. I commented out the codes and just retained the declarations.

推荐答案

好了,现在我知道了。感谢您的澄清。你的问题来自于被回收的意见。你应该看看这个帖子理解循环更好。

Ok now I got it. Thanks for the clarifications. Your problem comes from views being recycled. You should take a look at this post to understand recycling better.

基本上,当你使用 convertView getView(),要重复使用项目的看法不再可见。这就是为什么它的领域(包括微调,TextView的的价格...)已经设置的东西,你应该自己设定它们 getView()。这些值给这些文本框和微调应取决于项目时指定的位置

Basically, when you use the convertView in getView(), you are reusing the view of an item that is no longer visible. That's why its fields (including the spinner, the textview for the price...) are already set to something, and you should set them yourself in getView(). The values to give these textfields and the spinner should depend on the item at the specified position.

下面就是回收做(图片来自pviously提到的交$ P $服用):

Here's what recycling does (picture taken from the post previously mentioned):

下面时滚动以显示一个新的项目(比方说第8项,像画面),用于显示它是一样的一个用于第一项(第1项)的图。因此,当你选择的东西在第一项的微调,然后向下滚动,你会看到,在最后一个项目的变化太大,因为你的 getView 不改变被用于第1项的意见值(但它应该更新它们!)。

Here when you scroll to display a new item (let's say item 8, like the picture), the view used to display it is the same as the one for the first item (item 1). Therefore, when you select something on the spinner of the first item, and then scroll down, you will see the change in the last item too because your getView doesn't change the values of the views that were used for item 1 (but it is supposed to update them!).

注意:第一,你的情况的最后一个项目的对应关系完全是偶然。通常情况下,该视图重复使用2项近似地的项目数在一个屏幕高度分离的,因为你可以在图片中看到的。的

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项

The solution

C 窗体设计,tree view和listview和imagelist

Your not supposed to let the items behave as they please, but you're supposed to tell them what to display when you initialize the item view's content in getView(). For the picture above, this means you need to change what used to be item 1 into item 8.

您应该保持在你的适配器每个项目的状态。你可能有一个后备名单什么的,以显示你的的ListView不同的元素根据位置,对不对? 然后,你应该使用类似的列表(或相同)来存储的微调选择的值,由文本字段的价格显示的值等,这些或许应该对应于在当前列表中的项目领域,无论如何,所以你可能已经有一些地方来存储他们。

You should keep the state of each item in your adapter. You probably have a backing list or something to display different elements in your ListView depending on the position, right? Then you should use a similar list (or the same) to store the value selected in the spinner, the value displayed by the text field for the price etc. These should probably correspond to fields of the items in your current list anyway, so you probably already have some place to store them.

在另一方面,当你重新使用 convertView getView(),确保您初始化微调(和文本字段,一切都在这个项目视图)与该项目的正确值在位置

On the other hand, when you reuse the convertView in getView(), ensure you initialize the spinner (and text field, and everything in this item view) with the correct values for the item at position.

Viewholder v;

if (convertView == null) {
    // create a new holder for the new item view
    v = new Viewholder();
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    v.rowView = inflater.inflate(R.layout.inner_base_header_cutom, parent,false);
    v.rowView.setTag(v);

    // populate the new holder's fields
    v.spinner = (Spinner) v.rowView.findViewById(R.id.spinner1);
    v.itemPID = (TextView) v.rowView.findViewById(...); // put the right ID here
    v.itemPrice = (TextView) v.rowView.findViewById(...); // put the right ID here
    v.itemItemId = (TextView) v.rowView.findViewById(...); // put the right ID here
    v.subtotal =  (TextView) v.rowView.findViewById(...); // put the right ID here
} else {
    v = (Viewholder) convertView.getTag();
    // the views of v are already populated here (reused)     
}

/* 
 * Reused or not, the item view needs to be initialized here.
 * Initialize all views contained in v with values that are 
 * meaningful for the item at 'position'.
 */

// for instance:
MyItemClass theItemAtPosition = myBackingList.get(position);
v.subtotal.setText(String.valueOf(theItemAtPosition.getSubtotal()));
v.spinner.setSelection(theItemAtPosition.getQuantity());

// to be continued, you get the idea ;)
 
精彩推荐
图片推荐