opened
sockeqwe
username_0
The problem with ViewGroups as View is that they can't survive orientation changes, therefore you can't scope a Presenter to the view since the view will be destroyed (and the "scope" as well). So you have to scope the presenters to the surrounding Activity. The question is how to do that:

Mosby is build by following the delegation principle. That means that the creation of the presenter is not done directly in the ViewGroup which is the View in MVP (i.e. a custom FrameLayout), rather the creation (or reusing of the already existing presenter) will be done in a `MvpViewGroupDelegate` and then this delegate will be called in the FrameLayout to create presenter etc. (https://github.com/username_0/mosby/blob/master/mvp/src/main/java/com/hannesdorfmann/mosby/mvp/layout/MvpFrameLayout.java). 

So basically you have to provide can provide own `MvpViewGroupDelegate` which for instance has a map in the background which assigns every view an id and associates a presenter with it. So when the view gets destroyed during screen orientation changes the presenter will be kept in this map. After screen orientation changes you custom `MvpViewGroupDelegate` will not create a new Presenter for the view but rather uses the id of view (which has to be saved somehow in a Bundle or Parcel) to retrieve the already existing presenter instance from this internal "map". You might get some inspiration from that here http://hannesdorfmann.com/mosby/viewstate/ (scroll down unit the end, its described in the last section) 

So far so good, but there are two questions remaining:
1) When do we remove a presenter from this map? When the activity gets destroyed `Activity.isFinishing()` we should remove all Presenters, right? But how does your custom `MvpViewGroupDelegate` knows when the activity gets destoyed? The MvpViewGroupDelegate is part of the ViewGroup (i.e. FrameLayout). From FrameLayout we can recursively traverse the way up to retrieve the activity like this:

```java
  private Activity getActivity() {
      Context context = getContext();
      while (context instanceof ContextWrapper) {
          if (context instanceof Activity) {
              return (Activity)context;
          }
          context = ((ContextWrapper)context).getBaseContext();
      }
      return null;
  }
```

So now we can detect whether the activity will be destroyed because of orientation changes or not.

The next thing is where do we store the "map" of view id to presenter? as Singleton? That might work if you really really only have one single activity in your whole app. My recommendation would be to add a retaining headless (no UI) fragment. Then this "map" will only survive orientation changes and will be garbage collected (and all presenters too) when the activity will be finished.


2) The last thing we haven't discussed yet is when to release a presenter from this map because we have navigated in our app to another view. Well that depends on your navigation stack implementation. The navigation stack has to remove the presenter from the "map presenters" somehow. But I don't want to reinvent the wheel and come up with my own navigation stack. I would like to keep Mosby as simple as possible and as fundament / scaffold others can build there solution on top. I don't want that Mosby becomes a framework. Mosby should remain that tiny little library it is right now and not a huge complex framework.

I think Mosby 3.0 could work quite good with Pancakes library as navigation stack https://github.com/mattlogan/Pancakes
Retaining Presenter for ViewGroups
issue
created
Akkell
username_1
2) So we need to store a strong reference to the presenter as long as `Activity` is in the _Activity back stack_.
Seems there is [the way](https://habrahabr.ru/post/274635/). Didn't test it by myself yet. We can store the reference to presenter in the object of the class that extends `IBinder`. Then in `Activity.onSaveInstanceState()` (or `View.onSaveInstanceState()` if possible) we put this object into `Bundle` using the code from [BundleCompat](https://developer.android.com/reference/android/support/v4/app/BundleCompat.html) or alternative way from the article.
Bundle with this reference will be kept as long as `Activity` is in the _Activity back stack_. If we get our object back from Bundle - it will be the same object (with our reference). (if we do this in the same VM of course)
comment
closed
sockeqwe
username_0
issue
created
sockeqwe
username_0
Implemented in Presenter Manager.
comment