美文网首页
Android fragment 间数据传递

Android fragment 间数据传递

作者: 田田ww | 来源:发表于2021-10-14 18:04 被阅读0次

    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 间数据传递

          本文链接:https://www.haomeiwen.com/subject/hesuoltx.html