Эквивалент startActivityForResult() с Android Architecture Navigation

У меня рабочий процесс с 3 экранами. От "экрана 1" до доступа к "экрану 2" пользователь должен принять некоторые условия, которые я называю на своей картинке "модальными". Но он должен принять эти условия только один раз. В следующий раз, когда он находится на первом экране, он может перейти непосредственно к экрану 2. Пользователь может выбрать НЕ принимать условия, и поэтому мы возвращаемся к "экрану 1" и не пытаемся перейти к "экрану 2".

App workflow

Мне интересно, как это сделать с новым компонентом навигации.

Раньше что бы я это сделал:

  • На экране 1 проверьте, должен ли пользователь принять условия
  • Если нет, запустите "экран 2" деятельность
  • Если да, используйте startActivityForResult() и дождитесь результата от модального. Отметьте условия как принятые. Начать "экран 2"

Но с графиком навигации нет возможности запустить фрагмент, чтобы получить результат.

Я мог бы пометить термины как принятые на "модальном" экране и запустить "экран 2" оттуда. Дело в том, что для доступа к экрану 2 мне нужно сделать сетевой запрос. Я не хочу дублировать вызов API и обрабатывать его результаты как в "screen 1", так и в "модальном".

Есть ли способ вернуться с "модального" на "экран 1" с некоторой информацией (пользователь принял условия), используя навигацию Jetpack?

Изменение: в настоящее время я обойти это, используя тот же поток, который предлагает Яхья ниже: использование Activity только для модальных и использование startActivityForResult из "экрана 1". Мне просто интересно, смогу ли я продолжать использовать график навигации для всего потока.

Ответы

Ответ 1

Похоже, что сейчас нет эквивалента для startActivityForResult в компоненте навигации. Но если вы используете LiveData и ViewModel, вы можете быть заинтересованы в этой статье. Автор использует область видимости ViewModel и LiveData для достижения этого для фрагментов.

Ответ 2

Есть несколько альтернатив модели общего представления.

  1. забавный navigateBackWithResult (результат: Bundle), как описано здесь https://medium.com/google-developer-experts/using-navigation-architecture-component-in-a-large-banking-app-ac84936a42c2

  2. Создать обратный звонок.

ResultCallback.kt

interface ResultCallback : Serializable {
    fun setResult(result: Result)
}

Передайте этот обратный вызов в качестве аргумента (обратите внимание, что он должен реализовывать Serializable, а интерфейс должен быть объявлен в своем собственном файле.)

<argument android:name="callback"
                  app:argType="com.yourpackage.to.ResultCallback"/>

Сделайте framgent A реализующим ResultCallback, фрагмент B by получит аргументы и передаст через них данные, args.callback.setResult(x)

Ответ 3

Вы не указали какие-либо фрагменты кода, но вот некоторые из шагов, которые вы можете сделать:

1. На вашем экране 1 Активность:

  • Проверьте с помощью SharePreference, если он НЕ содержит ссылку на данные из предыдущего использования, это означает: либо это самое первое использование, либо в предыдущее время пользователь не принял условия. В этом случае startActivityForResult и перейдите на Modal Screen. В противном случае перейдите к Screen 2.

2. В вашей модальной деятельности:

  • Если пользователь принял условия, setResult(RESULT_OK, intent); и затем finish(); , В противном случае setResult(RESULT_REJECT, intent); и затем finish();

  • Вы обрабатываете результаты, происходящие из Modal активности в Activity Screen 1 с чем-то вроде этого:

    // This method is called when the Modal activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    
        // check that it is the Modal Activity with an OK result
        if (requestCode == REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                // store result in SharedPreference and/or send it to your database
                // go to Screen 2
            }else{
                // Stay here and do nothing / show a notification dialog ..etc
            }
        }
    }
    

Ответ 4

Есть еще один альтернативный способ. Вы можете использовать другое действие навигации от вашего модального обратно к screen1, вместо использования popBackStack(). На этом действии вы можете отправить любые данные, которые вам нравятся, чтобы просмотреть один. Используйте эту стратегию, чтобы убедиться, что модальный экран не сохраняется в заднем стеке навигации: fooobar.com/info/16115517/....

Единственная проблема, с которой я сталкиваюсь в этой стратегии, заключается в том, что нажатие кнопки "Назад" не отправит никаких данных назад, однако в большинстве случаев использования требуется переход после определенного действия пользователя, и в этих ситуациях этот обходной путь будет работать.