Save state of a CheckBox

3

I need to save the state of my CheckBox, they are inside a Spinner, and every time I open the Spinner it clears the CheckBox.

AdmList.java

        final String[] select_qualification = {
                "Todos", "1", "2", "3", "4",
                "5", "6"};
        Spinner spinner = (Spinner) findViewById(R.id.spinner);

        ArrayList<StateVO> listVOs = new ArrayList<>();

        for (int i = 0; i < select_qualification.length; i++) {
            StateVO stateVO = new StateVO();
            stateVO.setTitle(select_qualification[i]);
            stateVO.setSelected(false);
            listVOs.add(stateVO);
        }
        MyAdapter myAdapter = new MyAdapter(AdmListagem.this, 0,
                listVOs);
        spinner.setAdapter(myAdapter);

spinner_item2.xml

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

    <TextView
        android:id="@+id/text"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="25dp"
        android:paddingTop="10dp"
        android:paddingRight="10dp"
        android:paddingBottom="10dp"
        android:textSize="16dp"
        android:textColor="#000000"
        android:background="@drawable/spinner_item_border" />

    <CheckBox
        android:id="@+id/checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true" />
</RelativeLayout>

MyAdapter.java

public class MyAdapter extends ArrayAdapter<StateVO>  {
    private Context mContext;
    private ArrayList<StateVO> listState;
    private MyAdapter myAdapter;
    private boolean isFromView = false;
    String[] values;
    Boolean[] checkedStatus;

    public MyAdapter(Context context, int resource, List<StateVO> objects) {
        super(context, resource, objects);
        this.mContext = context;
        this.listState = (ArrayList<StateVO>) objects;
        this.myAdapter = this;
    }

    @Override
    public View getDropDownView(int position, View convertView,
                                ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }

    public View getCustomView(final int position, View convertView,
                              ViewGroup parent) {

        final ViewHolder holder;
        if (convertView == null) {
            LayoutInflater layoutInflator = LayoutInflater.from(mContext);
            convertView = layoutInflator.inflate(R.layout.spinner_item2, null);
            holder = new ViewHolder();
            holder.mTextView = (TextView) convertView
                    .findViewById(R.id.text);
            holder.mCheckBox = (CheckBox) convertView
                    .findViewById(R.id.checkbox);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.mTextView.setText(listState.get(position).getTitle());

        // To check weather checked event fire from getview() or user input
        isFromView = true;
        holder.mCheckBox.setChecked(listState.get(position).isSelected());
        isFromView = false;

        if ((position == 0)) {
            holder.mCheckBox.setVisibility(View.INVISIBLE);
        } else {
            holder.mCheckBox.setVisibility(View.VISIBLE);
        }
        holder.mCheckBox.setTag(position);
        holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int getPosition = (Integer) buttonView.getTag();
                String t = String.valueOf(getPosition);
                Toast.makeText(mContext, t, Toast.LENGTH_SHORT).show();

            }
        });
        return convertView;
    }

    private class ViewHolder {
        private TextView mTextView;
        private CheckBox mCheckBox;
    }
}

Statevo.java

public class StateVO {
    private String title;
    private boolean selected;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public boolean isSelected() {
        return selected;
    }

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

When you run the application and in Spinner choose the items, and click on the screen, and open the Spinner again it is without any CheckBox marking

    
asked by anonymous 13.09.2017 / 19:22

1 answer

2

I suppose the reason of the attribute selected of the StateVO class is for that very thing.

Adapter use it to save and retrieve the state of the CheckBox.

The part of recovering you already did. Missing the save part, which must be done in onCheckedChanged()

public View getCustomView(final int position, View convertView,
                          ViewGroup parent) {

    ...
    ...
    // To check weather checked event fire from getview() or user input
    isFromView = true;
    holder.mCheckBox.setChecked(listState.get(position).isSelected());
    isFromView = false;

    //holder.mCheckBox.setTag(position);
    holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isFromView)return;

            //int getPosition = (Integer) buttonView.getTag();
            String t = String.valueOf(position);
            Toast.makeText(mContext, t, Toast.LENGTH_SHORT).show();

            //Guarda o estado do CheckBox
            listState.get(position).setSelected(isChecked);

        }
    });
    return convertView;
}

Notes:

  • There is no need to save the position of the item in tag of the CheckBox. Since position is declared as final it is possible to use it within the onCheckedChanged() method.
  • I used flag isFromView so that the onCheckedChanged() method returns immediately so Toast is displayed only when the user clicks the CheckBox.
  • If you do not want to use the flag and continue to use the tag , to get the correct position in the onCheckedChanged() method, it must get the position value before line holder.mCheckBox.setChecked(listState.get(position).isSelected());
14.09.2017 / 12:25