onCheckedChangeListener

onCheckedChangeListener

虽然这是我想要的行为,但有人可以解释一下为什么会这样吗?

我有一个ListView,其中的自定义行包含CheckBoxTextView。这是行布局代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="horizontal">

    <CheckBox
        android:id="@+id/shop_list_checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/shop_list_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Sample text"
        />

</LinearLayout>


然后,我有了这个简单的数据模型(省略了一些方法和字段),基本上是一家拥有名称和选择状态的商店:

public class ShopListItem {

    //name of the shop
    private String name;

    //shop selection state
    private boolean isSelected;

    public ShopListItem(String shopKey, String name, boolean isSelected) {
        this.shopKey = shopKey;
        this.name = name;
        this.isSelected = isSelected;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selectionState) {
        this.isSelected = selectionState;
    }
}


这是我的自定义ArrayAdapter中的相关代码:

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

        // Temporary view to be returned as converterView
        View view;

        // Checking if view is reused or not
        if (convertView == null) { //new view is generated

            // Inflate new view and associate its views with viewHodler
            view = inflater.inflate(R.layout.row_shop_list, parent, false);
            final ViewHolder viewHolder = new ViewHolder();
            viewHolder.shopNameTextView = (TextView) view.findViewById(R.id.shop_list_textView);
            viewHolder.checkBox = (CheckBox) view.findViewById(R.id.shop_list_checkbox);

            // Asign check change listener
            viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    Log.i("i", "isChecked value is: "+isChecked+", buttonView.isChecked() value is: "+buttonView.isChecked());

                    // Get reference to the shop (data model) of checked row
                    ShopListItem shop = (ShopListItem) viewHolder.checkBox.getTag();

                    // Update selection state in data model
                    shop.setSelected(buttonView.isChecked());

                    listSelections(shopsArrayList);

                }
            });


            // Store viewHolder inside temporary view
            view.setTag(viewHolder);

            // Store reference to a shop (data model) of this row in the checkbox reference
            viewHolder.checkBox.setTag(shopsArrayList.get(position));

        } else {  //existing view reused

            // Assign view from adapter to temporary view
            view = convertView;

            // Get viewholder from view which was stored while generating new view
            ViewHolder storedHolder = (ViewHolder) view.getTag();

            //Store reference to a shop (data model) of this row in the checkbox reference
            storedHolder.checkBox.setTag(shopsArrayList.get(position));

        }

        // Get viewholder from view (from new view or converview)
        ViewHolder holder = (ViewHolder) view.getTag();

        // Populate holder references with data from shops array list
        holder.shopNameTextView.setText(shopsArrayList.get(position).getName());
        holder.checkBox.setChecked(shopsArrayList.get(position).isSelected());

        //return view
        return view;

    }


神秘之处在于OnCheckedChangeListener。每当我单击第一行的复选框时,侦听器都会收到正确的状态并更新商店数组列表的第一项(为true或false)。但是,如果我保留第一个复选框处于选中状态并向下滚动列表,则第一行离开屏幕后,状态为OnCheckedChangeListenerfalse就会被调用,但是商店数组列表的第一项不会更新为false 。为什么会这样呢?为什么仅在单击该框时才对其进行更新,而当其被隐藏时却不进行更新?

最佳答案

单击复选框后,OnCheckedChangeListener即被激活。当您上下滚动时,将为屏幕上的新行调用OTHER OnCheckedChangeListener。隐藏行的OnCheckedChangeListener没有被调用。

我想在您的情况下,您正在屏幕上看到新行的复选框值,这会使您感到困惑。尝试区分您的OnCheckedChangeListener's行中所引用的商店对象:

ShopListItem shop = (ShopListItem) viewHolder.checkBox.getTag();

10-08 03:18