Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formalize notion of child presenter #52

Closed
ghost opened this issue Mar 20, 2014 · 2 comments
Closed

Formalize notion of child presenter #52

ghost opened this issue Mar 20, 2014 · 2 comments

Comments

@ghost
Copy link

ghost commented Mar 20, 2014

PopupPresenters and other child presenters are kind of a pain to do right. You have to remember to call their takeView method from onLoad, and override your dropview method to call theirs.

Could we provide something like:

interface FindChildView<C, V> {
  C getChildView(V parentView);
}

<C> void loadChildPresenter(Presenter<C> child, FindChildView<C, V> findView) { ... }

Where V is the parent view's view type. loadChildPresenter would be called at the end of the parent's onLoad method, where we now call the child's takeView; and the call to the child's dropView would be automatic.

e.g.:

public void onLoad(Bundle b) {
  super.onLoad(b);
  loadChildPresenter(fooPopupPresenter, new FindChildView<FooPopup, MyView>() {
      FooPopup getChildView(MyView parent) { return parent.getFooPopup(); }
    });
}
@ghost
Copy link
Author

ghost commented Mar 20, 2014

Another thought is to make the new method addChildPresenter, to be called from the constructor or wherever. No load side effect in the method.

@ghost
Copy link
Author

ghost commented Mar 27, 2014

@loganj suggests that instead we should make dropView final, and encourage a pattern where Views are in charge of the wiring in hierarchical situations. That is, instead of

protected void onLoad(Bundle b) {
  super.onLoad(b);
  childPresenter.takeView(getView().getChildView());
}

protected void dropView(View view) {
  childPresenter.dropView(view.getChildView());
  super.dropView(view);
}

We do something like:

@Inject MyPresenter presenter;
final ChildView childView;

MyView(Context context, AttributeSet attrs) {
  super(context, attrs);
  Mortar.inject(context, this);
}

protected void onFinishInflate() {
  super.onFinishInflate();
  childView = new ChildView(getContext(), presenter.getChildPresenter());

  presenter.takeView(this);
}

protected void onDetachedFromWindow() {
  presenter.dropView(this);
  super.onDetachedFromWindow();
}

And we presume ChildView will take care of its own calls to takeView and dropView. The upside being a) dropView is final, less public api, yay! And b) it is always the case that views are in charge of takeView and dropView. Much more consistent, hopefully less confusing.

I think the thing to do is move the sample app to this style and see how it feels.

@ghost ghost closed this as completed Mar 27, 2014
@ghost ghost reopened this Mar 27, 2014
@rjrjr
Copy link
Collaborator

rjrjr commented May 11, 2014

I took a stab at this (making DropView final) and was thwarted by PopupPresenter. Will try again if we manage to kill that thing off

@rjrjr
Copy link
Collaborator

rjrjr commented Sep 24, 2014

Nope, don't make it more complicated. Make it simpler.

Lesson 1: always call dropView and takeView from the View side, even if you're nesting.

  @Override protected void onFinishInflate() {
    super.onFinishInflate();
    presenter.takeView(this);
    presenter.getSubPresenter().takeView(subView);
  }

Lesson 2: to hell with Popup, see #102

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant