问题描述
我正在使用android中的导航组件,其中最初设置了6个片段.问题是当我添加新片段(ProfileFragment)时.
I'm using the Navigation Component in android where I have set 6 fragments initially. The problem is when I added a new fragment (ProfileFragment).
当我从起始目标位置导航到此新片段时,按本机后退按钮不会弹出当前片段.相反,它只是停留在我所在的片段上-后退按钮什么也不做.
When I navigate to this new fragment from the start destination, pressing the native back button does not pop the current fragment off. Instead, it just stays to the fragment I'm in - the back button does nothing.
这是我的 navigation.xml :
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/dashboard_navigation"
app:startDestination="@id/dashboardFragment"
>
<fragment
android:id="@+id/dashboardFragment"
android:name="com.devssocial.localodge.ui.dashboard.ui.DashboardFragment"
android:label="DashboardFragment"
>
<action
android:id="@+id/action_dashboardFragment_to_newPostFragment"
app:destination="@id/newPostFragment"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
<action
android:id="@+id/action_dashboardFragment_to_notificationsFragment"
app:destination="@id/notificationsFragment"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
<action
android:id="@+id/action_dashboardFragment_to_mediaViewer"
app:destination="@id/mediaViewer"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
<action
android:id="@+id/action_dashboardFragment_to_postDetailFragment"
app:destination="@id/postDetailFragment"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
====================== HERE'S THE PROFILE ACTION ====================
<action
android:id="@+id/action_dashboardFragment_to_profileFragment"
app:destination="@id/profileFragment"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
=====================================================================
</fragment>
<fragment
android:id="@+id/profileFragment"
android:name="com.devssocial.localodge.ui.profile.ui.ProfileFragment"
android:label="fragment_profile"
tools:layout="@layout/fragment_profile"
/>
</navigation>
在上图中,突出显示的箭头(在左侧)是我遇到麻烦的导航操作.
In the image above, the highlighted arrow (in the left) is the navigation action I'm having troubles with.
在我的 Fragment 代码中,我的导航方式如下:
In my Fragment code, I'm navigating as follows:
findNavController().navigate(R.id.action_dashboardFragment_to_profileFragment)
其他导航操作正在按预期方式工作.但是由于某种原因,这个新添加的片段无法达到预期的效果.
The other navigation actions are working as intended. But for some reason, this newly added fragment does not behave as intended.
当我导航到ProfileFragment以及按返回按钮时,没有日志显示.
There are no logs showing when I navigate to ProfileFragment and when I press the back button.
我错过了什么吗?还是我的动作/片段配置有问题?
Am I missing something? or is there anything wrong with my action/fragment configurations?
我没有在 ProfileFragment 中执行任何操作.这是它的代码:
I do not do anything in ProfileFragment. Here's the code for it:
class ProfileFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_profile, container, false)
}
}
还有包含导航主机的活动xml :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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">
<fragment
android:id="@+id/dashboard_navigation"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/dashboard_navigation"
app:defaultNavHost="true"/>
</FrameLayout>
推荐答案
对于在上一片段(即家庭片段)中使用LiveData的任何人,只要您通过按后退"按钮返回到上一片段,片段就会开始观察数据,因为ViewModel幸免于该操作,所以它立即发出最后一个发出的值,在我的情况下,这打开了我按下后退按钮的Fragment,这样看来后退按钮不起作用,此解决方案使用的是发出数据的东西只有一次.我用了这个:
For anyone using LiveData in a previous Fragment which is a Home Fragment, whenever you go back to the previous Fragment by pressing back button the Fragment is starting to observe the data and because ViewModel survives this operation it immediately emits the last emitted value which in my case opens the Fragment from which I pressed the back button, that way it looks like the back button is not working the solution for this is using something that emits data only once. I used this :
class SingleLiveData<T> : MutableLiveData<T>() {
private val pending = AtomicBoolean()
/**
* Adds the given observer to the observers list within the lifespan of the given
* owner. The events are dispatched on the main thread. If LiveData already has data
* set, it will be delivered to the observer.
*
* @param owner The LifecycleOwner which controls the observer
* @param observer The observer that will receive the events
* @see MutableLiveData.observe
*/
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, Observer { t ->
if (pending.compareAndSet(true, false)) {
observer.onChanged(t)
}
})
}
/**
* Sets the value. If there are active observers, the value will be dispatched to them.
*
* @param value The new value
* @see MutableLiveData.setValue
*/
@MainThread
override fun setValue(value: T?) {
pending.set(true)
super.setValue(value)
}
这篇关于Android导航组件后退按钮不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!