Как получить результат из фрагмента с помощью компонента Navigation Architecture?

Скажем, что у нас есть два фрагмента: MainFragment и SelectionFragment. Вторая построена для выбора какого-либо объекта, например целого. Существуют разные подходы к получению результата от этого второго фрагмента, такого как обратные вызовы, шины и т.д.

Теперь, если мы решили использовать компонент Navigation Architecture, чтобы перейти ко второму фрагменту, мы можем использовать этот код:

NavHostFragment.findNavController(this).navigate(R.id.action_selection, bundle)

где bundle является экземпляром Bundle (конечно). Как вы видите, нет доступа к SelectionFragment где мы могли бы поставить обратный вызов. Вопрос в том, как получить результат с компонентом Navigation Architecture?

Ответ 1

Согласно Google: вы должны попытаться использовать общий ViewModel. Ниже приведен пример из Google:

Shared ViewModel, который будет содержать общие данные и может быть доступен из разных фрагментов.

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;
    }
}

MasterFragment, который обновляет ViewModel:

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

DetailsFragment, который использует общий ViewModel:

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.
        });
    }
}

Ответ 2

Недавно я начал вести проект, который широко использует JetPack Navigation. Это действительно трудно поддерживать, и навигация стала кошмаром. Чтобы смягчить это, я создал собственный фрагмент, который пытается заполнить некоторые пропущенные отверстия. Вот: https://github.com/pablichjenkov/Pack-Navigation

Проверьте это. Любые отзывы приветствуются.