在列表视图中保存切换按钮的状态

时间:2017-11-18 15:57:12

标签: android listview

我知道在listview中回收行。我有一个带有切换按钮的列表视图。正如很多帖子建议的那样,我在SparseBooleanArray中保存切换按钮的状态。我的问题是切换按钮行仍然在滚动上打开和关闭。在我的代码中,我保存了togglebutton的状态以及它们在数组中的相应位置,并且我从同一个数组中获取它们的状态。 感谢。

@Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View row = convertView;
        final ViewHolderBrandAvailability holder;
        if(row == null){
            dbHelper = new DBHelper(con);
            database = dbHelper.getWritableDatabase();
            LayoutInflater mInflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            //viewHolderBrandAvailability = new ViewHolderBrandAvailability();
            row = mInflater.inflate(R.layout.brand_availability_listview, parent, false);
            holder = new ViewHolderBrandAvailability();
            holder.brandNameTextView = (TextView) row.findViewById(R.id.brandAvailabilityNameText);
            holder.radioGroup = (ToggleButton) row.findViewById(R.id.brandAvailable);
            /*viewHolderBrandAvailability.unavailableRadioBtn = (RadioButton) convertView.findViewById(R.id.brandUnavailable);*/

            row.setTag(holder);
        }else {
            holder = (ViewHolderBrandAvailability) row.getTag();
        }

        holder.radioGroup.setTag(position);
        holder.radioGroup.setChecked(mCheckStates.get(position, false));

        holder.radioGroup.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                if(isChecked){

                    selectedBrandStatus.put(((BrandAvailability)list.get(position)).getBrand_id(), "Yes");

                }else {
                    selectedBrandStatus.put(((BrandAvailability)list.get(position)).getBrand_id(), "No");

                }
                mCheckStates.put((Integer) compoundButton.getTag(), isChecked);
            }
        });


        String brandTitle = ((BrandAvailability)list.get(position)).getBrand_title();
        holder.brandNameTextView.setText(brandTitle);
        //holder.radioGroup.setChecked();
        return row;
    }

    static class ViewHolderBrandAvailability {
        private TextView brandNameTextView;
        private ToggleButton radioGroup;
        //RadioButton unavailableRadioBtn;
        //int position;
    }

1 个答案:

答案 0 :(得分:0)

从您发布的代码中,我看到没有任何内容表明ToggleButton更改滚动的已检查状态存在问题。事实上,我创建了自己的适配器来测试你的代码,它对我来说非常好。

通常情况下,人们会遇到类似的问题,因为他们没有意识到他们在OnCheckedChangeListener的一次通话中设置的getView()会在下一次调用getView()时停留,并且所以setChecked()电话会触发它。但是,在您的情况下,您使用compoundButton.getTag()来确定mCheckStates数组的索引,因此这里没有问题。

话虽如此, 使用getView() position参数进行侦听器中的其他操作,此导致问题我如上所述。

selectedBrandStatus.put(((BrandAvailability)list.get(position)).getBrand_id(), "Yes");

想象getView()第一次被调用,位置为0.您的代码运行并分配监听器。最后检查位置0的ToggleButton,然后拨打selectedBrandStatus.put(list.get(0).getBrand_id(), "Yes")。现在滚动列表,直到此视图被回收:再次调用getView(),此视图将作为convertView传递。让我们称这个位置为20.你的听众仍然存在,所以当ToggleButton取消选中holder.radioGroup.setChecked(mCheckStates.get(20, false))时,它会再次被触发。现在它将使用"Yes"覆盖之前的"No",因为侦听器是使用position = 0创建的。

您只需将侦听器中的所有索引更改为(Integer) compoundButton.getTag()即可解决此问题。