簡體   English   中英

為什么Android Navigation Component 屏幕不返回上一個Fragment,而是調用了previos Fragment 的onViewCreated 中的一個方法?

[英]Why Android Navigation Component screen not go back to previous Fragment,but a method in onViewCreated of previos Fragment being called?

我有 2 個片段調用CreateRoomFragmentDisplayPhotoFragment ,導航圖如下所示:

<navigation>    
<fragment
    android:id="@+id/createRoomFragment"
    android:name="package.room.CreateRoomFragment"
    android:label="Create a room"
    tools:layout="@layout/fragment_create_room">
    <action
        android:id="@+id/action_createRoomFragment_to_roomFragment"
        app:destination="@id/roomFragment" />
    <action
        android:id="@+id/action_createRoomFragment_to_displayPhotoFragment"
        app:destination="@id/displayPhotoFragment" />
</fragment>

<fragment
    android:id="@+id/displayPhotoFragment"
    android:name="package.fragment.DisplayPhotoFragment"
    android:label="fragment_display_photo"
    tools:layout="@layout/fragment_display_photo" >
    <argument android:name="bitmap"
              app:argType="android.graphics.Bitmap"/>
</fragment>

所以當我想從CreateRoomFragment移動到DisplayPhotoFragment ,我使用如下方法:

NavDirections action = CreateRoomFragmentDirections.actionCreateRoomFragmentToDisplayPhotoFragment(selectedPhoto);
Navigation.findNavController(view).navigate(action);

這樣做,我可以導航到DisplayPhotoFragment

但是,當我按back了裝置的按鈕,也Back arrow從工具欄,它不能回去CreateRoomFragment

我試過這個,但仍然無法回到上一個片段:

requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(),
                new OnBackPressedCallback(true) {
                    @Override
                    public void handleOnBackPressed() {

                       navController.navigateUp();  //I tried this 
                       navController.popBackStack(R.id.createRoomFragment,false); //and also this
                    }
                });

現在主要問題:

使用上面的代碼,屏幕沒有回到之前的Fragment( CreateRoomFragment )。它仍然卡在DisplayPhotoFragment ,但同時調用了CreateRoomFragment onViewCreated部分的API方法。

這是什么原因造成的? 我該如何解決這個問題?

我有同樣的問題。 對我來說,問題是我使用 LiveData 布爾值來決定何時轉到下一個片段。 當我向后/向上導航時,布爾值仍然為真,因此它會再次自動向前導航。

Android 維護一個返回堆棧,其中包含您訪問過的目的地。 當用戶打開應用程序時,應用程序的第一個目的地被放置在堆棧中。 每次調用navigate()方法都會將另一個目標放在堆棧頂部。 Tapping Up 或 Back 分別調用NavController.navigateUp()NavController.popBackStack()方法,以從堆棧中移除(或彈出)頂部目標。

NavController.popBackStack()返回一個布爾值,指示它是否成功彈出回另一個目的地。 返回 false 的最常見情況是您手動彈出圖形的起始目的地。

當該方法返回 false 時, NavController.getCurrentDestination()返回 null。 您負責導航到新目的地或通過在您的 Activity 上調用finish()來處理彈出窗口。

使用操作進行導航時,您可以選擇使用操作的popUpTopopUpToInclusive參數從返回堆棧中彈出其他目的地。

class MyFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val onBackPressedCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (true == conditionForCustomAction) {
                    CustomActionHere()
                } else  NavHostFragment.findNavController(this@MyFragment).navigateUp();    
        }
    }
    requireActivity().onBackPressedDispatcher.addCallback(
        this, onBackPressedCallback
    )
    ...
}

使用實時數據處理導航的最佳解決方案是使用 SingleLiveEvent。

你總是可以使用這個類,它是 MutableLiveData 的擴展。

https://gist.githubusercontent.com/cdmunoz/ebe5c4104dadc2a461f512ea1ca71495/raw/a17f76754f86a4c0b1a6b43f5c6e6d179535e627/SingleLiveEvent.kt

有關此檢查的詳細信息:

https://proandroiddev.com/singleliveevent-to-help-you-work-with-livedata-and-events-5ac519989c70

有一個類似的問題。 我們仍然有多個帶有導航組件的活動。 所以想象一下活動 A -> 活動 B,活動 B 有自己的導航和片段。 當初始片段嘗試彈出返回堆棧時,無處彈出,導航控制器不知道要完成活動。 所以我找到的一個解決方案是做

if (!findNavController().popBackStack()) activity?.finish()

如果導航控制器無法彈出,它將完成活動。

如果您只想觀察事件一次,則可以在MutableLiveData上使用MutableSharedFlow

在您的viewModel

 private val _events = MutableSharedFlow<Event>()
    val events = _events.asSharedFlow() // read-only public view

    suspend fun postEvent() {
        _events.emit(event) // suspends until subscribers receive it
    }

在您的Activity/Fragment類中:

lifecycleScope.launchWhenStarted {
   viewModel.events.collect {
   }
}

viewModel.postEvent()

這將防止在返回片段時連續觀察數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM