marcelpinto / RxFlux

RxFlux is a small framework in order to follow Flux design pattern with RxJava functionalities
Apache License 2.0
326 stars 38 forks source link

Registering fragment inside another fragment #13

Closed eriuzo closed 8 years ago

eriuzo commented 8 years ago

Hi, I am using 0.3.2 (my own fork, as soon as you merge that PR, i will upgrade to 0.4.0)

I have use case like this:

Activity A loads Fragment B. Fragment B, on button press, can replace itself with Fragment C or D.

Fragment C and D isnt getting onRxStoreChanged, presumably because they arent registered.

I registered them on Fragment B, but looks like it isnt working. Is there a way to register them without creating an instance on Activity A? (the one instantiating C and D is B)

Also, just want to confirm, as of 0.3.2, the way to register fragments is like this right?

  @Override
  public void onRxViewRegistered() {
    dispatcher.subscribeRxView(fragment);
  }
coolfire2015 commented 8 years ago

I'm not familiar with English, I'm very sorry.onRxViewRegistered() is only called in onActivityStarted(),I registered Fragment B on Activity A success use @Override public void onRxViewRegistered() { dispatcher.subscribeRxView(fragment); }

eprendre commented 8 years ago

Suppose that all fragments are all inside Activity A,Not fragment inside fragment. Here's my solution:

Activity A

    @Override
    public void onAttachFragment(Fragment fragment)
    {
        super.onAttachFragment(fragment);
        if (fragment instanceof RxViewDispatch) {
            RxViewDispatch viewDispatch = (RxViewDispatch) fragment;
            viewDispatch.onRxViewRegistered();
            AppApplication.getInstance().getRxFlux().getDispatcher().subscribeRxView(viewDispatch);
        }
    }

Fragments implements RxViewDispatch

    @Override
    public void onRxViewRegistered() {
        rxFlux = AppApplication.getInstance().getRxFlux();
        apiActionCreator = ApiActionCreator.get(rxFlux.getDispatcher(), rxFlux.getSubscriptionManager());
        apiStore = ApiStore.get(rxFlux.getDispatcher());
    }
    @Override
    public void onDetach(){
        super.onDetach();
        rxFlux.getDispatcher().unsubscribeRxView(this);
    }

Note that Fragment B C D should not be instantiated from one Fragment, if so the following C or D might not be registered. Because the class name is used as a tag in subscribeRxView:

public <T extends RxViewDispatch> void subscribeRxView(final T object) {
    final String tag = object.getClass().getSimpleName();
    Subscription subscription = rxStoreMap.get(tag);
...
}

Hope @skimarxall got some time to fix this

eriuzo commented 8 years ago

Thanks for comments, I think I will try to change my approach.

@skimarxall so can I clarify that even though Fragments can implement RxViewDispatch, only Activities can register a Fragment? I think my confusion stems from that.

marcelpinto commented 8 years ago

@eriuzo if you get the instance of the dispatcher you can register any class that implements RxViewDispatch.

How do you get the instance is up to you. The thing is that then you have to take care of unregister this instance manually. RxFlux handles the activity lifecycle and does it for you.

The approach @eprendre took is right. What I need to change is using the tag to store the subscription. Since if we have two fragments of the same class they will overlap each other.

I will do that on the next PR

marcelpinto commented 8 years ago

@coolfire2015 yes onRxViewRegistered is called after the Activity is registered, that happens onStart. do you have a question or was just to answer @eriuzo?

coolfire2015 commented 8 years ago

@skimarxall No question ,thanks

eriuzo commented 8 years ago

@skimarxall

  1. I changed my approach so that Fragment B, C, D and the transitions among them are managed by Activity A. (the OnClickListener in Fragment B now calls a public method in Activity A). So I dont need for @eprendre 's solution for now.
  2. So RxFlux only handles Activity lifecycle. Do you plan to handle Fragment lifecycle sometime in the future? (Instead of doing it manually as described by @eprendre)
  3. What you meant by overlap, is that a second instance will not get callbacks?
marcelpinto commented 8 years ago

Hi,

  1. That's how the Fragment - Activity - Fragment communication should work, so I guess is okey.
  2. Yes, I will think on it but is dificult to follow the Fragment lifecycle without makeing it extend. So the same way as RxFlux class does.
  3. No, both would be registered but when unsubscribing them, just one would. So it could cause memory leaks. Needs to be fix