【问题标题】:Actionbar icon click and Up arrow click problem操作栏图标单击和向上箭头单击问题
【发布时间】:2020-05-19 06:51:20
【问题描述】:

我正在使用带有 navgraph 的 nav 组件。这就是我的导航图的设置方式:

主要活动 -> CategoriesFragment (Home Fragment) -> CategoryFragment -> PomoClockFragment

我执行以下导航CategoriesFragment -> CategoryFragment -> PomoClockFragment。

此时,重复按手机的物理后退按钮或Actionbar 的向上按钮可以正常使用片段返回堆栈。但是如果我按下Actionbar 中的一个图标来显示另一个片段,然后单击向上箭头,它会直接返回到主片段(CategoriesFragment),而不是返回到后堆栈上的最新片段。我该如何解决?我还尝试了其他方法,这些方法在下面的 onSupportNavigateUp() 方法中的活动代码中显示为 cmets。

主要活动

class MainActivity : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration

    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        Log.i("Lifecycle-Activity", "OnCreate() called")

        navController = Navigation.findNavController(this, R.id.navHostFragment)

        NavigationUI.setupActionBarWithNavController(this, navController)

        appBarConfiguration = AppBarConfiguration.Builder(navController.graph)
            .build()
    }

    override fun onSupportNavigateUp(): Boolean {

super.onSupportNavigateUp()

        return NavigationUI.navigateUp(navController, appBarConfiguration)

        //*** I also tried these, but does not solve the problem I am having ***

        //return Navigation.findNavController(this, R.id.navHostFragment).navigateUp() || super.onSupportNavigateUp()

        //supportFragmentManager.popBackStack()

        //return navController.navigateUp()

    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {

        Log.i("Lifecycle-Activity", "OnCreateOptionsMenu() called")

        menuInflater.inflate(R.menu.main_menu, menu)
        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        Log.i("Lifecycle-Activity", "OnOptionsItemSelected() called")

       return NavigationUI.onNavDestinationSelected(item, navController)  || super.onOptionsItemSelected(item)
    }

导航图

<?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/nav_graph_main"
    app:startDestination="@id/categoriesFragment">

    <fragment
        android:id="@+id/clockFragment"
        android:name="com.example.pomoplay.ui.main.ClockFragment"
        android:label="Pomo Clock"
        tools:layout="@layout/fragment_clock" />
    <fragment
        android:id="@+id/categoryFragment"
        android:name="com.example.pomoplay.ui.main.CategoryFragment"
        android:label="Category"
        tools:layout="@layout/fragment_category">
        <action
            android:id="@+id/action_categoryFragment_to_clockFragment"
            app:destination="@id/clockFragment" />
        <argument
            android:name="category"
            app:argType="com.example.pomoplay.Category"
            app:nullable="true"
            android:defaultValue="@null" />
        <action
            android:id="@+id/action_categoryFragment_to_newTaskDialogFragment"
            app:destination="@id/newTaskDialogFragment" />
        <argument
            android:name="pomotask"
            app:argType="com.example.pomoplay.PomoTask"
            app:nullable="true"
            android:defaultValue="@null" />
        <argument
            android:name="fromNewTaskDialog"
            app:argType="boolean"
            android:defaultValue="false" />
        <argument
            android:name="fromCategoriesFragmentTitle"
            app:argType="boolean"
            android:defaultValue="false" />
    </fragment>
    <fragment
        android:id="@+id/categoriesFragment"
        android:name="com.example.pomoplay.ui.main.CategoriesFragment"
        android:label="Categories"
        tools:layout="@layout/fragment_categories">
        <action
            android:id="@+id/action_categoriesFragment_to_newCategoryDialogFragment"
            app:destination="@id/newCategoryDialogFragment" />
        <argument
            android:name="category"
            app:argType="com.example.pomoplay.Category"
            app:nullable="true" />
        <action
            android:id="@+id/action_categoriesFragment_to_categoryFragment"
            app:destination="@id/categoryFragment" />
        <argument
            android:name="fromNewCategoryDialog"
            app:argType="boolean"
            android:defaultValue="false" />
    </fragment>
    <dialog
        android:id="@+id/newCategoryDialogFragment"
        android:name="com.example.pomoplay.ui.main.NewCategoryDialogFragment"
        tools:layout="@layout/fragment_new_category_dialog">
        <action
            android:id="@+id/action_newCategoryDialogFragment_to_categoriesFragment"
            app:destination="@id/categoriesFragment" />
    </dialog>
    <dialog
        android:id="@+id/newTaskDialogFragment"
        android:name="com.example.pomoplay.ui.main.NewTaskDialogFragment"
        android:label="fragment_new_task_dialog"
        tools:layout="@layout/fragment_new_task_dialog" >
        <action
            android:id="@+id/action_newTaskDialogFragment_to_categoryFragment"
            app:destination="@id/categoryFragment" />
    </dialog>
</navigation>

【问题讨论】:

    标签: android android-fragments android-actionbar android-navigation


    【解决方案1】:

    ActionBar 中向上箭头的默认操作是 NavigateUp,这会启动父活动,而不是完成当前活动。

    您需要在item.itemId == android.R.id.home 时覆盖onOptionItemSelected 并调用活动fragmentmanager.popStackBack() 方法(加上处理堆栈大小为0 并完成它) 调用onBackPressed()

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == android.R.id.home) {
            onBackPressed()
            return true
        }
    
        Log.i("Lifecycle-Activity", "OnOptionsItemSelected() called")
       return NavigationUI.onNavDestinationSelected(item, navController)  || super.onOptionsItemSelected(item)
    }
    

    【讨论】:

    • 但是在onOptionsItemSelected() 中有以下代码会阻止您的解决方案工作。我应该删除它吗?这是代码:NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item)
    • 你需要添加一个if
    • 我在Actionbar 中有一个图标,单击该图标会导航到主页片段CategoriesFragment。使用上面的代码,如果我单击此图标,它会将我带到主页片段,但向上箭头消失,现在如果单击手机的物理后退按钮,它将退出应用程序而不是遍历片段返回堆栈。如果可能的话,我能做些什么来解决这个问题。谢谢。
    • return NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item) 导致原始问题持续存在。我应该删除它吗?
    猜你喜欢
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多