Android MVP - 如何在活动演示者和片段演示者之间进行通信

Nor*_*tan 25 mvp android

我有一个包含3个片段的活动,目前我使用的是ViewPager.我想实现MVP并在活动演示者和片段演示者之间进行通信,即:

  • 将数据从活动演示者传递到片段演示者
  • 从片段演示者向活动演示者发送事件
  • ...

但我不知道如何以官方方式做到这一点.我可以使用BusEvent,但我认为这不是一个好习惯.

小智 5

片段和活动之间的通信或反之亦然可以通过使用 nnn 的答案来完成,或者您可以使用ViewModelLiveData女巫提供一种更清洁的方式并尊重生命周期,fragments并且activities可以避免编写几行代码以防止不可见fragment从后台接收数据。

首先扩展ViewModel类,初始化Livedata和一些辅助方法。

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;
}
Run Code Online (Sandbox Code Playgroud)

}

然后你初始化ViewModel你的活动。

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()));


}
Run Code Online (Sandbox Code Playgroud)

}

读取片段中的数据:

 @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
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

要更改任何实时数据的值,您可以在任何片段或活动中使用其中一种方法:

changeFragmentAData();
changeFragmentBData();
changeFragmentAllData();
Run Code Online (Sandbox Code Playgroud)

幕后发生了什么

当您使用时,mViewModel = ViewModelProviders.of(this).get(MyViewModel.class)您正在创建一个实例ViewModel并将其绑定到片段的给定活动的生命周期,因此视图模型仅是 destroidactivityfragement停止。如果您使用 mViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class)you are bindig it to the lifecycle if the parent活动`

当您使用mViewModel.getToFragmentA().observe()ormViewModel.getToFragmentB().observe()mViewModel.getToAllFragments().observe() 您将LiveDatainMyViewModel类连接到给定的片段或活动时,该onChange()方法的值将在所有观察该方法的类中更新。

我建议个人经验对Livedata结束进行一些研究ViewModel,您可以在youtube此链接上


小智 2

根据我的理解,对于您的用例,假设 ActivityA 有一个具有 3 个片段(FragmentA、FragmentB、FragmentC)的 viewPager。

ActivityA 有 ActivityPresenterA

FragmentA 有 FragmentPresenterA

根据 MVP,FragmentPresenterA 应该只负责 FragmentA 的所有逻辑和业务流程,并且只与 FragmentA 通信。因此,FragmentPresenterA无法直接与ActivityPresenterA通信。

对于从 Fragment 到 Activity 的通信,不应该涉及 Presenter,这应该像我们在非 MVP 架构中进行通信一样完成,即借助接口。

这同样适用于 Activity 与 Fragment 的通信。

对于 Activity 和 Fragment 之间的通信,请阅读此处