Переход к определенному фрагменту при запуске приложения из общего листа

Я использую Jetpack Navigation в своем приложении с одним действием и двумя фрагментами (фрагмент A, который также является домашним фрагментом, и фрагмент B, по которому можно перемещаться из фрагмента A).

К MainActivity, как показано ниже, добавлен intent-filter, который может принимать обычный текст.

 <activity android:name=".MainActivity"
        android:screenOrientation="portrait">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>

        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="@string/text_mime_type_text_plain"/>
        </intent-filter>
    </activity>

Когда пользователь выбирает мое приложение из общего листа Android, конечная цель - передать данные, полученные от намерения, во фрагмент B. В настоящее время я получаю намерение во фрагменте A (домашний фрагмент), а затем использую NavController для перехода к фрагменту B, используя приведенный ниже код.

  private fun checkReceivedIntent() {
    val receivedUrlIntent = activity?.intent
    val intentAction = receivedUrlIntent?.action
    val intentType = receivedUrlIntent?.type

    if (intentAction == Intent.ACTION_SEND && intentType != null) {
        if (intentType == getString(R.string.text_mime_type_text_plain) ) {
            val receivedText = receivedUrlIntent.getStringExtra(Intent.EXTRA_TEXT)
            val action = FragmentADirections.actionFragmentAToFragmentB(receivedText)
            findNavController().navigate(action)
        }
    }
}

Проблема в том, что при открытии фрагмента B при нажатии кнопки «Назад» или стрелки назад на панели инструментов (даже при многократном нажатии) фрагмент A не появляется, а фрагмент B продолжает появляться.

Я не знаю, что мне не хватает. Это правильный способ открыть конкретный фрагмент, когда приложение открывается пользователем из общего листа внутри другого приложения?

Изменить

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">

<fragment
    android:id="@+id/navHostFragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/nav_graph" />

<com.google.android.material.bottomappbar.BottomAppBar
    android:id="@+id/bottomAppBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    app:fabCradleMargin="8dp"

    />

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/fabMainActivity"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_add"
    app:layout_anchor="@id/bottomAppBar" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

person Mehul Kanzariya    schedule 06.11.2019    source источник
comment
Не могли бы вы рассказать, как вы определяете контейнер в своем XML-файле MainActivity? Также мне интересно, куда вы звоните checkReceivedIntent? Я предполагаю, что это внутри фрагмента А?   -  person Ibrahim Ali    schedule 08.11.2019
comment
@IbrahimAli Я обновил вопрос. Да, я вызываю checkReceivedIntent во фрагменте A.   -  person Mehul Kanzariya    schedule 08.11.2019
comment
В вашем <action в nav_graph.xml вы используете какой-нибудь popUp или что-то в этом роде при открытии фрагмента B?   -  person Ibrahim Ali    schedule 08.11.2019
comment
@IbrahimAli Нет.   -  person Mehul Kanzariya    schedule 08.11.2019
comment
checkReceivedIntent() будет вызываться каждый раз, когда вы пытаетесь загрузить фрагмент A, поэтому он продолжает переход к B, даже когда вы нажимаете назад   -  person JavaGhost    schedule 11.11.2019
comment
@MehulKanzariya Не могли бы вы уточнить. Значит, вы пытаетесь вернуться на Fragment A из Fragment B? И вы не можете этого сделать из-за навигации из таблицы. Верно?   -  person GensaGames    schedule 11.11.2019
comment
@JavaGhost Да, вы правы. Итак, есть ли другой предпочтительный способ сделать это?   -  person Mehul Kanzariya    schedule 12.11.2019
comment
после получения значений из намерений очистите его! поскольку он остается доступным, когда вы переходите к фрагменту A, он снова выбирает значения и переходит вперед ...   -  person Abdul Aziz    schedule 14.11.2019


Ответы (1)


Почему вы не можете напрямую перейти к Fragment B после получения Intent Extra в вашем Activity. Просто вместо определения Fragment в xml или как startDestination вы можете просто переключиться на Fragment B

В Activity:

       Navigation
            .findNavController(binding.root)
            .navigate(
                R.id.navigation_from_intent_actions, bundle,
                NavOptions.Builder()
                    .setIntentExtra(extras)
                    .build()
            )

ОБНОВЛЕНИЕ

Чтобы вернуться к предыдущему фрагменту, вы можете легко получить Fragment из FragmentManager (он не будет убит, потому что это ваш дом Fragment). Сделать это можно следующим образом:

  private fun returnWithName() {
      val name = name_input.text.toString()

      (targetFragment as? FragmentA)?.setName(name)
      activity?.supportFragmentManager?
           .popBackStackImmediate()
  }

А позже просто проверьте обновленный результат от FragmentB. К которому Fragment нужно перейти.

Примечание. Есть еще один способ поделиться данными с Shared ViewModel. Однако вам нужно будет перенести результат из ViewModel обратно в FragmentA. А затем проверьте новые параметры транзакции. Это также описано здесь.

person GensaGames    schedule 08.11.2019
comment
Поскольку фрагмент A уже установлен в качестве исходного пункта назначения, было бы неплохо пропустить его и напрямую перейти к фрагменту B? - person Mehul Kanzariya; 11.11.2019
comment
@MehulKanzariya Да, это совсем другое дело. Пожалуйста, проверьте обновленный ответ. - person GensaGames; 15.11.2019