Android fragment 间数据传递

Fragment间通信可采用的办法有如下几种:
本文参考一道面试题:介绍一下 Fragment 间的通信方式?

1、EventBus
2、Activity或parent fragment
3、viewmodel
4、Result API

1、基于EventBus通信

EventBus 使用方便限制少,但出现问题难定位,项目中过度使用会导致项目难以维护,不建议使用。

2、基于Activity或parent fragment通信

AndroidX更新前的fragment通信依赖于activity和父fragment回调进行通信,需手动配置较复杂。

3、viewmodel

不同fragment共用一个viewmodel,可在activity的scope中定义,订阅LiveData即可。

4、Result API

参考在 Fragment 之间传递数据

Fragment 1.3.0-alpha04开始,fragment可以通过共同的fragmentManager进行数据传递,示例如下

FragmentB -> FragmentA传递数据

1、两个fragment同级

FragmentA中设置setFragmentResultListener
Fragment B中设置setFragmentResult

//FragmentA
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getParentFragmentManager().setFragmentResultListener("key", this, new FragmentResultListener() {
        @Override
        public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
            // We use a String here, but any type that can be put in a Bundle is supported
            String result = bundle.getString("bundleKey");
            // Do something with the result...
        }
    });
}
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Bundle result = new Bundle();
        result.putString("bundleKey", "result");
        getParentFragmentManager().setFragmentResult("key", result);
    }
});

2、FragmentBFragmentA的父级

父级 Fragment 在调用setFragmentResultListener()时应使用 getChildFragmentManager() 而不是 getParentFragmentManager()

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // We set the listener on the child fragmentManager
    getChildFragmentManager().setFragmentResultListener("key", this, new FragmentResultListener() {
        @Override
        public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
            String result = bundle.getString("bundleKey");
            // Do something with the result..
        }
    });
}
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Bundle result = new Bundle();
        result.putString("bundleKey", "result");

        // The child fragment needs to still set the result on its parent fragment manager
        getParentFragmentManager().setFragmentResult("requestKey", result);
    }
});

ResultAPI 主要适用于那些一次性的通信场景(FragmentB返回结果后结束自己)。如果使用 ViewModel,需要上提到的 Fragment 共同的父级 Scope,而 Scope 的放大不利于数据的管理。

非一次性的通信场景,由于 FragmentA 和 FragmentB 在通信过程中共存,推荐通过共享 ViewModel 的方式,再借助 LiveData 等进行响应式通信。

你可能感兴趣的:(Android fragment 间数据传递)