Search code examples
androidmaterial-designswitchcompat

Switch Compat: onCheckedChanged


I'm trying to implement a settings activity in my android app where users can turn on and off the notification mode. To achieve that I'm using Switch Compat. Here is the layout. It's part of my activity layout.

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal"
    android:layout_marginStart="24dp"
    android:layout_marginTop="90dp"
    android:layout_marginEnd="16dp">

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/notifications"
        android:layout_gravity="start|center"
        android:layout_weight="1"
        android:textSize="20sp"
        android:textStyle="bold"
        android:id="@+id/notifications"/>


    <android.support.v7.widget.SwitchCompat
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/notificationsSwitch"
        android:layout_gravity="end|center"
        android:theme="@style/SwitchTheme"/>

</LinearLayout>

Here is the function which is responsive for the switch compat.

SwitchCompat notificationsSwitch;
AlertDialog alertDialog;
AlertDialog.Builder builder;

 @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_settings, container, false);
     notificationsSwitch = (SwitchCompat) view.findViewById(R.id.notificationsSwitch);

notificationsSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (!b) {
                    builder = new AlertDialog.Builder(getActivity());
                    builder.setMessage("Are you sure that you want to turn the Notifications off");
                    builder.setPositiveButton("Turn off ", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            notificationsSwitch.setChecked(false);
                        }
                    });
                    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            notificationsSwitch.setChecked(true);
                        }
                    });
                    alertDialog = builder.create();
                    alertDialog.show();
                    alertDialog.setCancelable(false);
                    alertDialog.setCanceledOnTouchOutside(false);
                    alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.alertDialogPositiveButton));
                    alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.alertDialogNegativeButton));
                } else {
                    builder = new AlertDialog.Builder(getActivity());
                    builder.setMessage("Are you sure that you want to turn the Notifications on");
                    builder.setPositiveButton("Turn on ", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            notificationsSwitch.setChecked(true);
                        }
                    });
                    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            notificationsSwitch.setChecked(false);
                        }
                    });
                    alertDialog = builder.create();
                    alertDialog.show();
                    alertDialog.setCancelable(false);
                    alertDialog.setCanceledOnTouchOutside(false);
                    alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.alertDialogPositiveButton));
                    alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.alertDialogNegativeButton));
                }
            }
        });

What I want to do ?

  • As I said this should give the users ability to turn on and off the notification.

What is wrong?

  • The code works fine except one bug and that bug is when user want to turn the notifications on for ex. and then change his mind and click Cancel on the dialog he will enter in a loop.

Why is this happening?

  • I have made the cancel to work on that way so if the user click Cancel the Switch Compat goes back to the previous position where it was before. But since I have method for that state so it triggers the other state and the user is in loop.

What i tried?

  • I tried by using switch but I can't pass the Boolean variable b.

  • I also tried using flag variable but i couldn't find the logic.

Does someone knows how I can overcome this. Thanks in advance.


Solution

  • You can use a flag as class attribute that will set true when click option in the Dialog, like IsFromDialog.

    then, inside the Onclick function in the dialogs, set IsFromDialog = true;

    And finally, at the start of the onCheckChanged you do

    If (!b && !IsFromDialog) { ... }