【问题标题】:How to intercept MainActivity's BottomNavigationView menu clicks from fragment如何从片段中拦截 MainActivity 的 BottomNavigationView 菜单点击
【发布时间】:2018-11-21 00:35:27
【问题描述】:

我的应用程序就像一个向导。我有一个 Activity 作为我所有片段的中心化。每个片段中都有一个带有“下一步”按钮的 BottomNavigationView,用于驱动向导。

当我想下一个时,我从 BottomNavMenu 调用“action_next”,它会导航到下一个片段。

但是当用户在该片段的上下文中按下下一步按钮时,我需要执行一些操作(例如存储输入的数据)。此外,如果用户输入的数据有任何问题,我需要取消导航。

第一次尝试我在我的片段中这样做:

val controller = NavHostFragment.findNavController(this)

        controller.addOnNavigatedListener { controller, navDestination: NavDestination ->

            when (navDestination.id) {
                R.id.destination_setup_tournment -> {
                    proceedNavigation(controller, navDestination)

                }

            }
        }


private fun proceedNavigation(controller: NavController, navDestination: NavDestination) {
    val teams = teamAdapter.getItems()
    if (validateSubmit(teams)){
        presenter.saveTeams(teams)
    }else{
        //how to cancel navigation and stay on this fragment?
    }
}

但它对我来说看起来并不好,甚至不正确,如果出现问题,我不知道如何取消导航。

App相关文件如下:

主活动:

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?colorPrimary"
    android:theme="@style/ToolbarTheme" />

<fragment
    android:id="@+id/nav_host_fragment"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:navGraph="@navigation/navigation"
    app:defaultNavHost="true" />
<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_nav_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    app:menu="@menu/bottom_nav"
    style="@style/Widget.MaterialComponents.BottomNavigationView"
    >


</com.google.android.material.bottomnavigation.BottomNavigationView>

bottom_nav.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/action_next" android:title="@string/tornment_mode" android:icon="@drawable/ic_navigate_next_black_24dp" />

</menu>

【问题讨论】:

  • 为什么要使用 BottomNavigationView 来实现类似流程的向导? BottomNavigationView 用于在应用的不同部分之间进行全局导航。
  • 我的意图是使用与此活动相关的所有片段共有的东西,只是在每个片段的上下文中更改按钮执行的命令,但保持导航流。

标签: android kotlin bottomnavigationview android-jetpack android-architecture-navigation


【解决方案1】:

没有办法“取消”导航事件 - 您需要将业务逻辑放在按钮/侦听器本身上,并且只有在您真正想要导航时才调用 navigate()

Creating event callbacks to the activity documentation 介绍了一种将 Activity 和 Fragment 连接在一起的方法,即使用 onAttach(Context) 获取对 Activity 的引用并设置属性、回调等。

例如,您可能会考虑执行以下操作:

// In your Activity
var onNextClicked: () -> Unit = {}

// In your Activity's onCreate()
button.setOnClickListener = View.OnClickListener {
  onNextClicked.invoke()
}

// In your Fragment
override fun onAttach(context: Context) {
  (context as YourActivity).onNextClicked = {
    val teams = teamAdapter.getItems()
    if (validateSubmit(teams)){
      presenter.saveTeams(teams)
      findNavController().navigate(R.id.action_next)
    }
  }
}

每个 Fragment 都会设置他们希望下一个按钮执行的操作,让您完全控制按钮的操作。

如果您在 BottomNavigationView 上死定了,而不仅仅是使用实际的 Button,您可能希望设置自己的 OnNavigationItemSelectedListener 并让该侦听器调用 onNextClicked lambda(如果您使用此示例)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 2019-05-02
    • 2011-04-22
    • 1970-01-01
    相关资源
    最近更新 更多