0

Is this a proper way of communication between fragments ?

public class MainActivity extends AppCompatActivity implements IFragmentsHandler {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //...
    }

    @Override 
    protected void startFragment1() {
        Fragment1 f1 = new Fragment1();
        f1.setFragmentsHandler(this);
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, f1)
                .commit();
    }

    @Override
    protected void startFramgment2() {
        Fragment1 f2 = new Fragment1();
        f2.setFragmentsHandler(this);
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, f2)
                .commit();            
    }
}

public class Fragment1 {
    private IFragmentsHadnler fragmentsHandler;

    @Override
    public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {

        final View view = inflater.inflate(R.layout.fragment1, container, false);
        //...Code...
        fragmentsHandler.startFragment1();
    }

    public void setFragmentsHandler(IFragmentsHandler fragmentsHandler) {
        this.fragmentsHandler = fragmentsHandler;
    }
}

public class Fragment2 {
    private IFragmentsHadnler fragmentsHandler;

    @Override
    public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {

        final View view = inflater.inflate(R.layout.fragment2, container, false);
        //...Code...
        fragmentsHandler.startFragment2();
    }

    public void setFragmentsHandler(IFragmentsHandler fragmentsHandler) {
        this.fragmentsHandler = fragmentsHandler;
    }
}

[EDIT1] : Posted the Interface (though it was obvious)

public interface IFragmentsHandler {
    public void startFragment1();
    public void startFragment2();
}

From my Java perspective this will throw OutOfMemoryError but I'm not if it is the same for the Android. Anyway what is the preferred way of communication between fragments?

tur1ng
  • 1,082
  • 1
  • 10
  • 24
  • exactly what you mean by communication? And, how are you overriding the `protected void startFragment1() ` method in an AppCompatActivity? – Arun Shankar Mar 18 '17 at 10:34
  • @ArunElectra Ok I will add the interface as well. By communication I mean starting Fragment2 from Fragment1. – tur1ng Mar 18 '17 at 10:40
  • you want to replace fragment1 with fragment2 and initiate the replacement from fragment1? – Arun Shankar Mar 18 '17 at 10:47
  • Don't forget to override onAttach method. Did you have a look to this answer? http://stackoverflow.com/questions/13700798/basic-communication-between-two-fragments – Chakir Mar 18 '17 at 10:48
  • You have a never ending recursion. You start fragment2 in fragment1's `onCreate` and fragment1 in fragment2's `onCreate` method – Titus Mar 18 '17 at 10:48
  • @Jameltheone This is deprecated. – tur1ng Mar 18 '17 at 10:49
  • 1
    @JAAAY if you're talking about onAttach method, what's deprecated is public void onAttach(Activity activity) but it was replaced by public void onAttach(Context context) – Chakir Mar 18 '17 at 10:52
  • @Titus When I say //...Code... that means it can by anything there, in my mind I have calling startFragment1() inside a Listener inside onCreateView(). But anyway how to implement this (having 2 fragments and can switch between them whenever I want) ? – tur1ng Mar 18 '17 at 10:54
  • 1
    If that is the case, this should work, it won't throw `OutOfMemoryError` because the fragments that are no longer visible should be destroyed by the garbage collector. Instead of setting the `IFragmentsHadnler` the way your doing it you can also do something like this: `public void onAttach(Activity activity) {super.onAttach(activity);fragmentsHandler = (IFragmentsHadnler) activity;}` – Titus Mar 18 '17 at 11:06
  • @Titus This method is deprecated. I 'll try Jameltheone's answer. – tur1ng Mar 18 '17 at 11:07

3 Answers3

1

According to android developer guide, communication between fragments is done through the associated Activity.

A fragment use his interface to communicate with the Activity. And the Activity deliver a message by capturing the Fragment instance with findFragmentById() or creating one if needed, then directly call the other fragment's public methods.

  • Fragment1 wants to pass some data: uses his interface method implemented by Activity.
  • Activity executes that method receiving the data, create&replace or find (depending on your layout) the Fragment2 and pass this data or execute some public method on fragment2 class (depending on your layout).
  • Fragment2 extract data from bundle or execute (depending on your layout) his public method to receive the data.

I think the problem in your code is you are misunderstanding interface purpose. You are using for start the same fragment who is calling the method. Fragment1 is calling startFragment1() in his onCreateView(), but it is already started.

If you needed, in here there is a good tutorial.

jorgeavilae
  • 208
  • 1
  • 9
0

To communicate between components consider app architecture MVP, VIPER, etc. On code side it may use event bus for communication or just plain callbacks.

  • Do navigation in one place
  • Do business logic in another place
  • Do present-view logic in presenter
  • Do view logic in views, fragments, adapters
  • I understand this is the proper way of doing it but I only have 2 fragments, I really don't want to mess with architecture. Can you provide an example? – tur1ng Mar 18 '17 at 11:00
0

As you started, you can use interfaces to communicate between Fragments as suggested by Google.

But an easy way to communicate between fragments is by using event bus (which implements the publish/subscribe pattern) like EventBus library.

You can also use RxJava to create your own event bus and thus make communications between components of your app (have a look to this Stackoverflow question: RxJava as event bus?)

Community
  • 1
  • 1
Chakir
  • 488
  • 4
  • 10