Android:将数据从子片段传递到父片段

gos*_*eib 9 android android-fragments

我需要将子片段中的一些数据传递给父片段,当我返回到父片段时,我将能够读取该片段.详细地:

我有一个FragmentActivity调用FragmentParent.从FragmentParent我像这样调用FragmentChild:

FragmentChild fragmentChild = new FragmentChild();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frl_view_container, fragmentChild);
transaction.addToBackStack(null);
ctransaction.commit();
Run Code Online (Sandbox Code Playgroud)

在FragmentChild中,我设置了一个字符串值,我需要将其传递回FragmentParent,然后返回FragmentParent.

String result = "OK";
getFragmentManager().popBackStack();
Run Code Online (Sandbox Code Playgroud)

在FragmentParent中读取结果字符串的最佳/正确方法是什么?

Man*_*ani 44

Android架构组件解决方案:

如果您使用的是Android架构组件,则可以在所有FragmentsActivitya 之间共享数据ViewModel.确保ViewModelProviders使用Activity上下文来创建ViewModels.

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}

public class MasterFragment extends Fragment {
    private SharedViewModel model;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        model.getSelected().observe(this, { item ->
           // Update the UI.
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

非Android架构组件解决方案:

您可以使用setTargetFragmentonActivityResult来实现此目的.

将FragmentParent实例设置为FragmentChild实例上的目标片段即

FragmentChild fragmentChild = new FragmentChild();
fragmentChild.setTargetFragment(this, FRAGMENT_CODE);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frl_view_container, fragmentChild);
transaction.addToBackStack(null);
transaction.commit();
Run Code Online (Sandbox Code Playgroud)

在FragmentChild中,无论您在何处调用popBackStack,都要在set target Fragment上调用onActivityResult.使用Bundle传递其他数据.

Intent intent = new Intent();
intent.putExtra(FRAGMENT_KEY, "Ok");
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
getFragmentManager().popBackStack();
Run Code Online (Sandbox Code Playgroud)

回到FragmentParent,重写默认的onActivityResult方法.

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == FRAGMENT_CODE && resultCode == Activity.RESULT_OK) {
        if(data != null) {
           String value = data.getStringExtra(FRAGMENT_KEY);
           if(value != null) {
              Log.v(TAG, "Data passed from Child fragment = " + value);
           }
        }
    }
}  
Run Code Online (Sandbox Code Playgroud)