Updating fragment from Activity Using Rxjava Android
Asked Answered
M

2

17

I have a simple use case where:

  • Activity1 create a fragment1

  • fragment1 after creation notify to activity that it is created and update its activity1 views.

  • activity1 after getting notification update fragment1 views.

I am using rxandroid , sublibrary rxlifecycle components and android , but i am still in learning phase , there was not even rx-lifecycle tag on stackoverflow , so i am still struggling to understand the flow of this library..

Edit

I prefer not to use EventBus , it's just like everyone shouting at everyone to do something, so Rxjava Observable approach will be much useful

Meunier answered 16/11, 2016 at 16:12 Comment(5)
Why do you want the Activity to call a Fragment function? What exactly are you doing?Hardunn
its just a use case where i am basically doing network call in activity and when i am done i am drawing polyline in map fragment which is seperate fragment replaced within framelayout of activity , but problem is lifecycle , i don't know when will fragment get created , so i don't get null context in fragmentMeunier
You can use onAttach to get a reference to the Context/Activity, and, call whatever method, or you can do the network request entirely in the Fragment. I'm not sure about Rx stuff, thoughHardunn
EventBus may be useful for such situationsSmattering
In question as i have mentioned , i have to change views of fragment and activity , which is right now much pain to handle,, In rxjava i think there should be a better way to do this,Meunier
I
6

For posting information from fragment to activity, you should use an event bus for informing activity about fragment creation (replacement to the callbacks and the mess they created).

Sample code for event bus with RxJava is:

public class SampleEventsBus {
    private static final String TAG = SampleEventsBus.class.getSimpleName();
    private static final String TAG2 = SampleEventsBus.class.getCanonicalName();

    public static final int ACTION_FRAGMENT_CREATED = 1;
    public static final int ACTION_FRAGMENT_OTHER = 2;

    private static SampleEventsBus mInstance;

    public static SampleEventsBus getInstance() {
        if (mInstance == null) {
            mInstance = new SampleEventsBus();
        }
        return mInstance;
    }

    private SampleEventBus() {}

    private PublishSubject<Integer> fragmentEventSubject = PublishSubject.create();

    public Observable<Integer> getFragmentEventObservable() {
        return fragmentEventSubject;
    }

    public void postFragmentAction(Integer actionId) {
        fragmentEventSubject.onNext(actionId);
    }
}

Then from your fragment you can call:

SampleEventsBus.getInstance().postFragmentAction(SampleEventsBus.ACTION_FRAGMENT_CREATED);

from onAttach() or onViewCreated() or any place you prefer.

Also, in activity you will need to put the following code to listet to your event bus:

SampleEventsBus .getInstance().getFragmentEventObservable().subscribe(new Subscriber<Integer>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(Integer actionId) {
            if(actionId == SampleEventsBus.ACTION_FRAGMENT_CREATED) {
                //do any required action
            }
        }
    });

For the second part, i.e. to update the fragment from activity, I won't recommend using this method as it will lead to unnecessary complexity, Instead use the "original way" as:

  1. Create a method in Fragment as updateView(Object obj)
  2. In onNext(), get the desired fragment as SampleFragment fragment = (SampleFragment)getSupportFragmentManager().findFragmentByTag("TAG");
  3. call fragment.updateView(obj);

Hope this helps.

Insure answered 28/11, 2016 at 1:54 Comment(0)
V
6

Two points to consider:

  1. Just because you use an EventBus does not mean that it needs to be global. You can have multiple event buses if you want, and you can just share a single one between two components (Activity and Fragment).

  2. There are several examples in the RxJava documentation that show how to implement event bus functionality using RxJava

By Using an event bus, you can simplify things greatly, by disassociating the whole process from the Android lifecycle.

Verbify answered 20/11, 2016 at 17:32 Comment(2)
1 thing i really hate about EventBus is that it listen to single object type , so what if i need to communicate on some particular event say click on activity may result in updating of view in fragment , and it is basically giving string to fragment and from activity vice versa , which can only mean i have to create 2 separate classes , just to make this communication possible using eventbus!!!Meunier
or you can receive some BaseEvent, containing event type and then use 'Command' design pattern - store handlers of that event in map, take the right one and process that event. I've got to do that once while refactoring codeStavro
I
6

For posting information from fragment to activity, you should use an event bus for informing activity about fragment creation (replacement to the callbacks and the mess they created).

Sample code for event bus with RxJava is:

public class SampleEventsBus {
    private static final String TAG = SampleEventsBus.class.getSimpleName();
    private static final String TAG2 = SampleEventsBus.class.getCanonicalName();

    public static final int ACTION_FRAGMENT_CREATED = 1;
    public static final int ACTION_FRAGMENT_OTHER = 2;

    private static SampleEventsBus mInstance;

    public static SampleEventsBus getInstance() {
        if (mInstance == null) {
            mInstance = new SampleEventsBus();
        }
        return mInstance;
    }

    private SampleEventBus() {}

    private PublishSubject<Integer> fragmentEventSubject = PublishSubject.create();

    public Observable<Integer> getFragmentEventObservable() {
        return fragmentEventSubject;
    }

    public void postFragmentAction(Integer actionId) {
        fragmentEventSubject.onNext(actionId);
    }
}

Then from your fragment you can call:

SampleEventsBus.getInstance().postFragmentAction(SampleEventsBus.ACTION_FRAGMENT_CREATED);

from onAttach() or onViewCreated() or any place you prefer.

Also, in activity you will need to put the following code to listet to your event bus:

SampleEventsBus .getInstance().getFragmentEventObservable().subscribe(new Subscriber<Integer>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(Integer actionId) {
            if(actionId == SampleEventsBus.ACTION_FRAGMENT_CREATED) {
                //do any required action
            }
        }
    });

For the second part, i.e. to update the fragment from activity, I won't recommend using this method as it will lead to unnecessary complexity, Instead use the "original way" as:

  1. Create a method in Fragment as updateView(Object obj)
  2. In onNext(), get the desired fragment as SampleFragment fragment = (SampleFragment)getSupportFragmentManager().findFragmentByTag("TAG");
  3. call fragment.updateView(obj);

Hope this helps.

Insure answered 28/11, 2016 at 1:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.