0

I am new to Android development and am having a question about multiple switch buttons, how to retrieve values ​​smartly, and make this data available for other activities?

Currently, I am implemented the save of the button state and retrieval of the information found in the current activity as followed:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    switchButtonOne = findViewById(R.id.switchButtonOne);
    switchButtonOne.setChecked(true);

    switchButtonTwo = findViewById(R.id.switchButtonTwo);
    switchButtonTwo.setChecked(false);

    //...... (In total there are 5 switch buttons)

    //switchButtonOne
    switchButtonOne.setOnCheckedChangeListener((compoundButton, isChecked) -> {
        if(isChecked){
            stringArrayList.add("1");
        }else {
            stringArrayList.remove("1");
        }
        getArray(stringArrayList);
        //SAVE
        sharedPreferences[0] = PreferenceManager
                .getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences[0].edit();
        editor.putBoolean("1", switchButtonOne.isChecked());
        editor.commit();
    });
    switchButtonOne.setChecked(sharedPreferences[0].getBoolean("1", false));

    //switchButtonTwo
    switchButtonTwo.setOnCheckedChangeListener((compoundButton, isChecked) -> {
        if(isChecked){
            stringArrayList.add("2");
        }else {
            stringArrayList.remove("2");
        }
        getArray(stringArrayList);
        //SAVE
        sharedPreferences[0] = PreferenceManager
                .getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences[0].edit();
        editor.putBoolean("2", switchButtonTwo.isChecked());
        editor.commit();
    });
    //.......
}

I am sure there is a more efficient way to implement this and I would gladly appreciate effective resources to learn the best practices of making information and Activity state available between Activities.

Big thanks in advance

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
  • i dont understand what is the problem, can you explain in a better way what are you trying to do? – Jhon Fredy Trujillo Ortega Jan 23 '18 at 14:08
  • Hello, John! I'd like to know how I can make this code smaller and better. I think the code got too long and repetitive. Another thing I would like to do is to save the switch button status and make it available to other activities, as these buttons will be a filter that will later fetch a json file to filter the result into other activities (this is the settings activity) – user2950020 Jan 23 '18 at 14:45

2 Answers2

0

One option is to use only one listener for all five buttons. You would do this like so:

public class MyActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
    Switch[] buttons;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        buttons = new Switch[5];
        Switch switchButtonOne = findViewById(R.id.switchButtonOne);
        switchButtonOne.setOnCheckedChangeListener(this);
        switchButtonOne.setChecked(sharedPreferences[0].getBoolean("1", false));
        buttons[0] = switchButtonOne;

        Switch switchButtonTwo = findViewById(R.id.switchButtonTwo);
        switchButtonTwo.setOnCheckedChangeListener(this);
        switchButtonTwo.setChecked(sharedPreferences[1].getBoolean("2", false));
        buttons[1] = switchButtonTwo;

        //...... (In total there are 5 switch buttons)
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        int index;
        switch (buttonView.getId()) {
            case R.id.switchButtonOne:
                index = 0;
                break;
            case R.id.switchButtonTwo:
                index = 1;
                break;
                ...
        }
        if (isChecked) {
            stringArrayList.add(String.valueOf(index + 1));
        } else {
            stringArrayList.remove(String.valueOf(index + 1));
        }
        getArray(stringArrayList);
        //SAVE
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences[index].edit();
        editor.putBoolean(String.valueOf(index + 1), buttons[index].isChecked());
        editor.commit();
    }
}

At this point the code is not much shorter than yours, however, as soon as you add your other three buttons, you will see than the code for all buttons ends up being considerably shorter and more concise.

It would be great to have a BooleanArray for the SharedPreferences, however, such a class does not exist. A workaround can be found here.

EDIT

Looking at your question and your full code again, I would suggest a different approach. You don't need any OnCheckedChangeListener at all. Simply save the state of your buttons whenever the activity is left (onPause) and restore state once the activity is resumed (onResume). A side effect is that the code gets much shorter.

public class MainActivity extends Activity {
    Switch[] buttons;
    int numberOfButtons = 5;
    SharedPreferences sharedPreferences;

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

        buttons = new Switch[numberOfButtons];
        sharedPreferences = getSharedPreferences("YourPreferenceName", MODE_PRIVATE);

        for (int i = 0; i < numberOfButtons; i++) {
            buttons[i] = findViewById(getResources().getIdentifier("switchButton" + String.valueOf(i + 1), "id", getPackageName()));
        }
    }

    public void onPause() {
        super.onPause();
        for (int i = 0; i < numberOfButtons; i++) {
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putBoolean(String.valueOf(i + 1), buttons[i].isChecked());
            editor.apply();
        }
    }

    public void onResume(){
        super.onResume();
        for (int i = 0; i < numberOfButtons; i++) {
            buttons[i].setChecked(sharedPreferences.getBoolean(String.valueOf(i + 1), false));
        }
    }
}

Please note that, in your layout xml, you have to change the ids of your switches to the following: switchButton1, ..., switchButton5.

kalabalik
  • 3,792
  • 2
  • 21
  • 50
  • I really liked your code! That's exactly what I was looking for! But it happens an error when I click on the activity. Apparently it is returning null the isChecked() virtual method. Can you tell me why this happens? Thanks again @kalabalik `java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.widget.Switch.isChecked()' on a null object reference` – user2950020 Jan 24 '18 at 11:23
  • Occuring in the second to last line? What is `index` when it occurs? – kalabalik Jan 24 '18 at 11:26
  • The point of the error message is **not** that instead of a boolean it returns `null`, but that the object on which `isChecked` is called is `null`. – kalabalik Jan 24 '18 at 11:43
  • I tried to debug the code to see in which index it is giving error but not achieved! When I remove setChecked() it appears another error: `java.lang.ArrayIndexOutOfBoundsException: length=1; index=1` Complete code: [link](https://paste.ofcode.org/HvB8k6Vk5RYiYnUPU7i7PM) – user2950020 Jan 24 '18 at 12:12
  • In `onCreate`, you should give each of the booleans a key from 1 to 5. Otherwise this code doesn't work anymore: `editor.putBoolean(String.valueOf(index + 1), buttons[index].isChecked());` However, this will not be the source of the error message. – kalabalik Jan 24 '18 at 12:24
  • @user2950020 How about marking the answer as correct? (I know you cannot upvote yet, however, setting the check is possible even with little rep.) – kalabalik Jan 25 '18 at 16:13
  • Sorry @kalabalik! – user2950020 Jan 29 '18 at 23:04
0

You can Implement CompoundButton.OnCheckedChangeListener for whole activity and then set listener for all switch you have used.Handle all switch in single callback onCheckedChanged.

public class SwitchActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
    Switch switchButtonOne;
    Switch switchButtonTwo;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {

        super.onCreate(savedInstanceState, persistentState);
        switchButtonOne = findViewById(R.id.switchButtonOne);
        switchButtonOne.setChecked(true);

        switchButtonTwo = findViewById(R.id.switchButtonTwo);
        switchButtonTwo.setChecked(false);

        switchButtonOne.setOnCheckedChangeListener(this);
        switchButtonTwo.setOnCheckedChangeListener(this);
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        switch (buttonView.getId()) {
            case R.id.switchButtonOne:
                //Handle Code for switchButtonOne
                break;
            case R.id.switchButtonTwo:
                //Handle Code for switchButtonOne
                break;
        }
    }
}
Patrick R
  • 6,621
  • 1
  • 24
  • 27