为 Fragment1 的结果调用 Fragment2

Call Fragment2 for result from Fragment1

我有一个基础 Activity,其中有 2 个片段(比如说 Fragment1 和 Fragment2) 我需要从 Fragment1 调用 Fragment2 来捕获数据,然后在 Fragment1 中使用它。

我知道 Activity 的结果调用可以在 baseActivity 的 ActivityResult 中获取,但是我将如何从 Fragment1 调用 Fragment2 来获得结果?

我想你会从这个解决方案中得到提示。因为我不能为你的要求写代码,但这会给你一个想法,你可以做什么。

public class Fragment1 extends android.support.v4.app.Fragment {
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof ActivityHome) {
            ((ActivityHome) context).setFragment1(this);
        }
    }
}

public class ActivityHome extends AppCompatActivity {
    Fragment1 fragment1;

    public void setFragment1(Fragment1 fragment1) {
        this.fragment1 = fragment1;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (fragment1 != null) fragment1.onActivityResult(requestCode, resultCode, data);
    }
}

即使您可以使用接口来实现它,但我建议您 EventBus 因为这是一个微型库,它使通信变得非常容易。

(1) 制作数据Class

public static class MessageEvent { /* Additional fields if needed */ }

(2) 订阅活动

@Subscribe(threadMode = ThreadMode.MAIN)  
public void onMessageEvent(MessageEvent event) {/* Do something */};

(3) 注册和注销

 @Override
 public void onStart() {
     super.onStart();
     EventBus.getDefault().register(this);
 }

 @Override
 public void onStop() {
     super.onStop();
     EventBus.getDefault().unregister(this);
 }

并从任何地方触发

 EventBus.getDefault().post(new MessageEvent());

没有 MVVM

我猜最简单的内置方法是使用 Fragment.setTargetFragment(@Nullable Fragment fragment, int requestCode)

来自片段 1:

val fragment = Fragment2.newInstane()
fragment.setTargetFragment(this, 10)

当您想将结果返回到片段 1 时,从片段 2:

fun setResultBack(){
    val intent = Intent()
    // inject anything to intent here
    getTargetFragment().onActivityResult(10, Activity.RESULT_OK, intent)
    fragmentManager.popBackStack()
}

最终覆盖片段 1 中的 onActivityResult

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if(requestCode == 10){
        // handle result here
    } 
    else super.onActivityResult(requestCode, resultCode, data)
}

即使在恢复片段状态或更改配置后,这在所有情况下都有效。

与 MVVM

使用 documentation

推荐的共享视图模型

我建议查看这种紧密耦合和重构,这样片段就不会那么紧密耦合,并且数据获取也同样解耦。查看有关 MVP、MVC 或 MVVP 的各种资源以了解概念。

不过,有时您确实需要将一个片段的信息传达给另一个片段。 typical/recommended 方法是定义片段需要的 "fragment callback" 接口,该接口由 Activity 实现。因此 Activity 是通信的媒介(有助于分离片段。)您可以为片段使用自定义基础 class,以便它们具有通用的接口定义。

public class MyBaseFragment extends Fragment {
    public interface FragmentCallbacks {
        //  Use whatever arguments you may require here
        void fetchData();
    }

    protected FragmentCallbacks  mCallbacks;

    @Override
    void onAttach(Context context) {
        try {
            mCallbacks = (FragmentCallbacks)context;
        } catch (ClassCastException e) {
            throw new RuntimeException("Activity must implement FragmentCallbacks");
        }
    }
}

现在,在 Fragment1 中,您可以调用 mCallbacks.fetchData()Activity 可以使用它调用您在 Fragment2 中创建的 public 方法。当它取回数据时(可能是异步的),它可以通过您创建的 public 方法将其提供给 Fragment1