Question:
I decided to do everything "the right way", so I started translating the old project with noodle code into Moxy.
I have one activity that shows multiple fragments. Question: how (where?) to correctly implement the change of fragments?
It seems to me that there are three options:
-
Implement in all fragments
MainView extends MvpView
, which will contain theshowFragment()
method, and override it in each fragment separately. That is, the fragment itself will call another fragment. But this, kmk, is not entirely true – as far as I remember, fragments should still be managed by Activity. -
Make
MainView extends MvpView
, make theshowFragment(String tag)
method in it, Override this method in the Activity so that different fragments are shown depending on the tag. Make the methodpublic MainPresenter getPresenter()
in the same Activity. Then fragments will change each other via Activity:getActivity().getPresenter().showFragment("Tag")
. I'm not sure that this is correct from the point of view of MVP, besides, it's a little confusing. -
Change the presenter Activity's type to
PresenterType.GLOBAL
. I haven't quite figured this out yet.
None of these options seem right to me. So a hint is needed.
So far, I'm doing @InjectPresenter
presenter from Activity in the fragment (and accordingly, I have to do implements MainView
), and I call the fragment change method on this presenter. But this, as expected, does not work, since the method overridden in the fragment from MainView
empty.
public class FragmentA extends MvpAppCompatFragment implements AView, MainView {
private static final String ARGS = "args";
public static final String MAIN_FRAGMENT = "main";
@InjectPresenter
APresenter aPresenter;
@InjectPresenter
MainPresenter mainPresenter;
@ProvidePresenter
ExploitTypePresenter provideTitlePresenter() {
int type = getArguments().getInt(ARGS_TYPE);
return new ExploitTypePresenter(type);
}
public static FragmentA getInstance(int intArgs) {
FragmentA fragment = new FragmentA();
Bundle args = new Bundle();
args.putInt(ARGS, intArgs);
fragment.setArguments(args);
return fragment;
}
public FragmentA() {
super();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
Butterknife.bind(this, view);
return view;
}
@OnClick(R.id.save_button) void onSave() {
aPresenter.onSaved();
mainPresenter.showFragment(MAIN_FRAGMENT);
}
@Override
public void showFragment(String tag) {
}
}
Answer:
There are several options for how to implement fragment switching or in other words "navigation" in your particular case (one single-activity with its own presenter to display fragments) or similar.
In general, the task actually sounds like this – how to establish "communication" between different presenters:
-
Add a new layer of "interactors" through which presenters will communicate with each other. Presenters at the host activity and fragments will have an instance of the "interactor" through which they will exchange events / messages – this can be done on listeners or, better, on the Rx approach – an observer sits in the interactor and presenters who are interested in it follow its changes.
-
Communicate through activities. Get an interface for the activity and keep a link to it in your fragments, the fragment presenters will call the methods of the fragments and they will pull the activity interface, and it will do / switch something there. In fact, we can say that this is communication "through view" and it may seem that this is "wrong", but this method is acceptable and the place to be – fragments do not live by themselves in any case, one way or another they need an activity and we eventually need a fragment manager.
-
Tighten the Cicerone library, store a copy of the Chicheronevsky router in presenters and pull this router to switch fragments. This option, when using MVP and Moxy in particular, is the most suitable, so there are very few examples of Moxy without Cicerone on the Internet.
Also on YouTube there is an excellent report from the authors of "Moxy. How to use it correctly? / Yuri Shmakov (Arello Mobile)" – I advise you to view