Search code examples
androidcheckboxsharedpreferencessavestate

onSaveInstanceState or SharedPreferences for multiple CheckBoxes?


I have been trying for a few days now to correctly implement the onSaveInstanceState() method, but with no success up until now.

What am I doing wrong? My code does not return an error, but the state of the checkboxes is not saved?

Is it ok to implement the onSaveInstanceState() method?

Would it be better if I used SharedPreferences?

What I want is not to lose the checkbox selection on rotating the screen. If anyone can correct what I am doing I would be grateful!

Here is what I have:

MainActivity.java:

package com.example.alex.savepreferencescheckbox;

import android.annotation.SuppressLint;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    AlertDialog dialog;
    CheckBox cbAllDay, cbBefore12, cbBetween1216, cbBetween1620, ccbAfter20;
    Boolean myBoolean1, myBoolean2, myBoolean3, myBoolean4, myBoolean5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    public void alertDialog(View view) {

        if (dialog == null) {

            AlertDialog.Builder builder;
            builder = new AlertDialog.Builder(this);
            LayoutInflater inflater = this.getLayoutInflater();
            @SuppressLint("InflateParams") View checkBoxView = inflater.inflate(R.layout.markers_filtering, null);
            builder.setView(checkBoxView);
            cbAllDay = (CheckBox) checkBoxView.findViewById(R.id.checkBox1);
            cbBefore12 = (CheckBox) checkBoxView.findViewById(R.id.checkBox2);
            cbBetween1216 = (CheckBox) checkBoxView.findViewById(R.id.checkBox3);
            cbBetween1620 = (CheckBox) checkBoxView.findViewById(R.id.checkBox4);
            ccbAfter20 = (CheckBox) checkBoxView.findViewById(R.id.checkBox5);


            dialog = builder.create();

        }
        dialog.show();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("CheckBox1", cbAllDay.isChecked());
        outState.putBoolean("CheckBox2", cbBefore12.isChecked());
        outState.putBoolean("CheckBox3", cbBetween1216.isChecked());
        outState.putBoolean("CheckBox4", cbBetween1620.isChecked());
        outState.putBoolean("CheckBox5", ccbAfter20.isChecked());

    }


    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        myBoolean1 = savedInstanceState.getBoolean("CheckBox1");
        myBoolean2 = savedInstanceState.getBoolean("CheckBox2");
        myBoolean3 = savedInstanceState.getBoolean("CheckBox3");
        myBoolean4 = savedInstanceState.getBoolean("CheckBox4");
        myBoolean5 = savedInstanceState.getBoolean("CheckBox5");
    }

    public void applyFilter(View view) {

        dialog.dismiss();

        if (cbAllDay.isChecked()){
            Toast.makeText(this, "The first box was checked", Toast.LENGTH_SHORT).show();

        } else if (cbBefore12.isChecked()){
            Toast.makeText(this, "The second box was checked", Toast.LENGTH_SHORT).show();

        } else if (cbBetween1216.isChecked()){
            Toast.makeText(this, "The third box was checked", Toast.LENGTH_SHORT).show();

        } else if (cbBetween1620.isChecked()){
            Toast.makeText(this, "The forth box was checked", Toast.LENGTH_SHORT).show();

        } else if (ccbAfter20.isChecked()){
            Toast.makeText(this, "The fifth box was checked", Toast.LENGTH_SHORT).show();

        }
    }

    public void doNothing(View view) {

        dialog.dismiss();
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.alex.savepreferencescheckbox.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/textView" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button"
        android:layout_marginTop="71dp"
        android:layout_below="@+id/textView"
        android:layout_alignParentStart="true"
        android:onClick="alertDialog"/>
</RelativeLayout>

markers_filtering.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Choose Your Hour!"
        android:textSize="25sp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="10dp"
        android:layout_gravity="center"
        android:id="@+id/title_hour_selection"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title_hour_selection"
        android:layout_marginLeft="30dp"
        android:layout_marginStart="30dp"
        android:text="All day long" />

    <CheckBox
        android:id="@+id/checkBox2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginStart="30dp"
        android:text="Before 12 P.M."
        android:layout_below="@+id/checkBox1"/>

    <CheckBox
        android:id="@+id/checkBox3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/checkBox2"
        android:layout_marginLeft="30dp"
        android:layout_marginStart="30dp"
        android:text="Between 12.00 P.M. - 16.00 P.M." />

    <CheckBox
        android:id="@+id/checkBox4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/checkBox3"
        android:layout_marginLeft="30dp"
        android:layout_marginStart="30dp"
        android:text="Between 16.00 P.M. - 20.00 P.M." />

    <CheckBox
        android:id="@+id/checkBox5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginStart="30dp"
        android:layout_below="@+id/checkBox4"
        android:text="After 20.00 P.M."
        android:layout_marginBottom="10dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OK"
        android:layout_marginLeft="30dp"
        android:layout_marginStart="30dp"
        android:layout_marginBottom="30dp"
        android:layout_below="@+id/checkBox5"
        android:id="@+id/okButton"
        android:onClick="applyFilter"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Cancel"
        android:id="@+id/cancelButton"
        android:layout_below="@+id/checkBox5"
        android:layout_alignRight="@+id/checkBox5"
        android:layout_alignEnd="@+id/checkBox5"
        android:layout_marginRight="30dp"
        android:layout_marginEnd="30dp"
        android:layout_marginBottom="30dp"
        android:onClick="doNothing"/>


</RelativeLayout>

Solution

  • New Edit:

    I made a similar project like yours and tested it. Your code looks fine but only thing you forgot is to set up your checkboxes in alertDialog() method with the saved values provided by onRestoreInstanceState() method.

    Here is the full code of MainActivity.java:

    package com.example.alex.savepreferencescheckbox;
    
    import android.annotation.SuppressLint;
    import android.os.Bundle;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.CheckBox;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
        AlertDialog dialog;
        CheckBox cbAllDay, cbBefore12, cbBetween1216, cbBetween1620, ccbAfter20;
        Boolean myBoolean1, myBoolean2, myBoolean3, myBoolean4, myBoolean5;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void alertDialog(View view) {
    
            if (dialog == null) {
    
                AlertDialog.Builder builder;
                builder = new AlertDialog.Builder(this);
                LayoutInflater inflater = this.getLayoutInflater();
                @SuppressLint("InflateParams") View checkBoxView = inflater.inflate(R.layout.markers_filtering, null);
                builder.setView(checkBoxView);
    
                cbAllDay = (CheckBox) checkBoxView.findViewById(R.id.checkBox1);
                if (myBoolean1 != null) {
                    cbAllDay.setChecked(myBoolean1);
                }
                cbBefore12 = (CheckBox) checkBoxView.findViewById(R.id.checkBox2);
                if (myBoolean2 != null) {
                    cbBefore12.setChecked(myBoolean2);
                }
    
                cbBetween1216 = (CheckBox) checkBoxView.findViewById(R.id.checkBox3);
                if (myBoolean3 != null) {
                    cbBetween1216.setChecked(myBoolean3);
                }
    
                cbBetween1620 = (CheckBox) checkBoxView.findViewById(R.id.checkBox4);
                if (myBoolean4 != null) {
                    cbBetween1620.setChecked(myBoolean4);
                }
    
                ccbAfter20 = (CheckBox) checkBoxView.findViewById(R.id.checkBox5);
                if (myBoolean5 != null) {
                    ccbAfter20.setChecked(myBoolean5);
                }
    
                dialog = builder.create();
            }
            dialog.show();
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putBoolean("CheckBox1", cbAllDay.isChecked());
            outState.putBoolean("CheckBox2", cbBefore12.isChecked());
            outState.putBoolean("CheckBox3", cbBetween1216.isChecked());
            outState.putBoolean("CheckBox4", cbBetween1620.isChecked());
            outState.putBoolean("CheckBox5", ccbAfter20.isChecked());
        }
    
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
            myBoolean1 = savedInstanceState.getBoolean("CheckBox1");
            myBoolean2 = savedInstanceState.getBoolean("CheckBox2");
            myBoolean3 = savedInstanceState.getBoolean("CheckBox3");
            myBoolean4 = savedInstanceState.getBoolean("CheckBox4");
            myBoolean5 = savedInstanceState.getBoolean("CheckBox5");
        }
    
        public void applyFilter(View view) {
    
            dialog.dismiss();
    
            if (cbAllDay.isChecked()) {
                Toast.makeText(this, "The first box was checked", Toast.LENGTH_SHORT).show();
            } else if (cbBefore12.isChecked()) {
                Toast.makeText(this, "The second box was checked", Toast.LENGTH_SHORT).show();
            } else if (cbBetween1216.isChecked()) {
                Toast.makeText(this, "The third box was checked", Toast.LENGTH_SHORT).show();
            } else if (cbBetween1620.isChecked()) {
                Toast.makeText(this, "The forth box was checked", Toast.LENGTH_SHORT).show();
            } else if (ccbAfter20.isChecked()) {
                Toast.makeText(this, "The fifth box was checked", Toast.LENGTH_SHORT).show();
            }
        }
    
        public void doNothing(View view) {
    
            dialog.dismiss();
        }
    }
    

    and here are the screenshots of the emulator (Galaxy Nexus API 23, it works with the API 16 too, I've tested it):

    Portrait mode:

    Galaxy Nexus Api 23 Portrait mode

    Landscape mode:

    Galaxy Nexus Api 23 Landscape mode