I have an activity with 3 fragments, currently I use ViewPager. I want to implement MVP and communicate between activity presenter and fragment presenters i.e:
But I don't know how to do it in official way. I can use BusEvent but I don't think it's a good practice.
In order to allow fragments and activities to communicate we need to capture an instance of our interface and cast it into the context of the activities we need to communicate with. Thankfully, we can do this in something called the onAttach() method.
Example of MVP Architecture The role of the Presenter class is to keep the business logic of the application away from the activity. Below is the complete step-by-step implementation of this android application. Note that we are going to implement the project using both Java and Kotlin language.
Communication between fragments and activity or vice-versa can be done by using nnn's answer or you could use ViewModel
and LiveData
witch provides a cleaner way and respect the lifecycle from fragments
and activities
which can save from writing a few lines of code in attempt to prevent a a non-visible fragment
from receiving data on the background.
First you extend the ViewModel
class, initialize the Livedata
and some helper methods.
public class MyViewModel extends ViewModel { private MutableLiveData<String> toFragmentA, toFragmentB; private MutableLiveData<List<String>> toAllFragments; public MyViewModel() { toFragmentA = new MutableLiveData<>(); toFragmentB = new MutableLiveData<>(); toAllFragments = new MutableLiveData<>(); } public void changeFragmentAData(String value){ toFragmentA.postValue(value); } public void changeFragmentBData(String value){ toFragmentB.postValue(value); } public void changeFragmentAllData(List<String> value){ toAllFragments.postValue(value); } public LiveData<String> getToFragmentA() { return toFragmentA; } public LiveData<List<String>> getToAllFragments() { return toAllFragments; } public LiveData<String> getToFragmentB() { return toFragmentB; }
}
Then you initialize the ViewModel
on your activity.
public class MainActivity extends AppCompatActivity { private ViewPager viewPager; private TabLayout tabLayout; MyViewModel mViewModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewModel = ViewModelProviders.of(this) .get(MyViewModel.class); viewPager.setAdapter(new Adapter(getSupportFragmentManager())); }
}
reading the data in the fragments:
@Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class); mViewModel.getToAllFragments().observe(this, new Observer<List<String>>() { @Override public void onChanged(List<String> s) { myList.addAll(s); //do something like update a RecyclerView } }); mViewModel.getToFragmentA().observe(this, new Observer<String>() { @Override public void onChanged(String s) { mytext = s; //do something like update a TextView } }); }
to change the values of any of the live datas you can use one of the methods in any of the fragments or in the activity:
changeFragmentAData(); changeFragmentBData(); changeFragmentAllData();
Whats happing behind the scenes:
when you use mViewModel = ViewModelProviders.of(this).get(MyViewModel.class)
you are creating a n instance of ViewModel
and binding it to the lifecycle of the given activity of fragment so the view model is destroid only the the activity
or fragement
is stopped. if you use mViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class)you are bindig it to the lifecycle if the parent
activity`
when you use mViewModel.getToFragmentA().observe()
or mViewModel.getToFragmentB().observe()
or mViewModel.getToAllFragments().observe()
you are connecting the LiveData
in MyViewModel
class to the given fragment or activity an the value of the onChange()
method is updated in all the classes that are observing the method.
I recomend for personal expirience a bit of research about Livedata
end ViewModel
which ou can on youtube or this link
As per my understanding, for your UseCase, suppose ActivityA have a viewPager having 3 Fragments(FragmentA, FragmentB, FragmentC).
ActivityA have ActivityPresenterA
FragmentA have FragmentPresenterA
As per MVP, FragmentPresenterA should be responsible for all the logical and business flows of FragmentA only and should communicate with FragmentA only. Therefore, FragmentPresenterA can not directly communicate with ActivityPresenterA.
For communication from Fragment to Activity, presenter should not be involved and this should be done as we would communicate in non-MVP architecture, i.e. with the help of interface.
Same applies for Activity to Fragment communication.
For communication between Activity and Fragment read here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With