0

Is it possible for two (switch) buttons to have synchronized behavior between fragments? i.e: When button A is switched on in fragment A, I want button B's appearance in fragment B to also appear switched on.

How would I do that? The end goal is to have a global button on either fragment.

Bread
  • 71
  • 1
  • 13

4 Answers4

1

That would depend on whether both fragments are on same activity. If they are, then all you need is a boolean flag on the said activity and synchronise depend on that.

If not, then maybe create an boolean preference and synchronise based on that. Hope this helps. If you need code examples, let me know.

public interface Listener {
 public boolean getFlag();
 public void setFlag(boolean enable);
}

public class SomeActivity extends AppCompatActivity implements Listener {
// getFlag, setFlag implementation
}

public class FragmentA {
 private boolean state;
 private Listener listener;
 private Switch switchBtn;

 public void onAttach(Context ctx){
  listener = (Listener) this.getActivity();
  // check for ClassCast Exception
 }
 public void onActivityCreated() {
   state = listener.getFlag();
   switchBtn.setChecked(state);
 }
}

For details view this page

f0f1
  • 35
  • 4
1

You can use a boolean flag in your activity and set it false by default and when any of switch is pressed on in either fragment then set its value to true, and when you navigate to another fragment then check flag value and if its true then switch it on or else off.

ray1195
  • 106
  • 11
1

Sample of communication between Fragments. Example below is modified from Communicating with Other Fragments

Step 1. Create an interface

public interface ButtonCallback{
    void onClick(boolean val)
}

Step 2. In the HostActivity which hosts both fragment A and B, make HostActivity implements interface ButtonCallback.

public class HostActivity extends AppCompatActivity implements ButtonCallback{

    void onClick(boolean val){
    }
}

Step 3. In fragment A & B, initialize the callback with casting the activity

class FragmentA extends Fragment{

    ButtonCallback callback;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        //Make sure activity host implement ButtonCallback interface
        try {
            callback= (ButtonCallback ) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
            + " must implement ButtonCallback");
        }
    }

    //public method to update fragment's button state
    public void setGlobalButtonState(boolean val){
        //globalButton has been initialized in onCreateView function
        globalButton.setEnabled(val);
    }
}

class FragmentB extends Fragment{

    ButtonCallback callback;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        try {
            callback= (ButtonCallback ) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
            + " must implement ButtonCallback");
        }
    }

    public void setGlobalButtonState(boolean val){
        //globalButton has been initialized in onCreateView function
        globalButton.setEnabled(val);
    }
}

Step 4. In Fragment A, call ButtonCallback.onClick(boolean) when user click on the button

globalButton.setOnClickListener(new View.OnClickListener(View v){
    Boolean value  = !v.isEnabled();
    callback.onClick(value)
});

Step 5. In HostActivity's onClick function, find a way to get Fragment B that suis your context, and update the button in Fragment B via the setGlobalButtonState function

void onClick(boolean val){
    //get Fragment B.
    fragmentB.setGlobalButtonState(val);
}

Additional note, if the button meant to be global, it might worth to consider to put the button on the host Activity instead if that suits your context.

hjchin
  • 864
  • 2
  • 8
  • 25
  • In step 1, should the interface be created within my base fragment class? – Bread Aug 03 '18 at 00:41
  • 1
    you can do that if that suits your need. Design is always to solve a problem, if u see it suitable, I would agree with you to create a base fragment. – hjchin Aug 03 '18 at 02:32
  • In Step 3, "onAttach(Activity... " is deprecated. Changing the word "Activity" to "Context" fixes the error. How will this impact the rest of the code? Can it run on KitKat Api? – Bread Aug 05 '18 at 21:15
  • As shown here: https://stackoverflow.com/questions/32083053/android-fragment-onattach-deprecated – Bread Aug 05 '18 at 21:17
  • Fragment's onAttach(Context) is in the package android.support.v4.app. As long as you're using support library then it is fine. Please mark this as answer if it answered your question. – hjchin Aug 06 '18 at 03:17
  • I don't think this code works with a switch. I've tried modifying it and get too many syntax errors. – Bread Aug 07 '18 at 00:27
  • 1
    i missed out a brace and I fixed it. – hjchin Aug 07 '18 at 01:27
  • One last thing, the error "non-static method 'setGlobalButtonState(boolean)' cannot be referenced from a static context" appears in MainActivity. – Bread Aug 07 '18 at 20:47
  • this is the fragment class. https://github.com/hjchin/POS/blob/master/app/src/main/java/pos/com/pos/discount/view/DiscountListFragment.java. you can find onAttach, callback interface definition and the callback in the adapter class DiscountAdapter. – hjchin Aug 08 '18 at 01:18
  • I think it is good to post your code, i.e. your progress so that you can learn and remove error one by one. for the last error you see, i think you are using the fragment class not fragment instance. You need to get the fragment instance of FragmentB by using appropriate method such as https://developer.android.com/reference/android/support/v4/app/FragmentManager.html#findFragmentById(int) – hjchin Aug 08 '18 at 01:24
0

Here is the developer guide on communicating with other fragments: https://developer.android.com/training/basics/fragments/communicating . In the activity have the shared attribute. In each fragment, go to the parent activity to get that attribute on button click. To reduce dependency, use an interface to obtain the data from the activity, as shown in the link provided