在 FAB 单击时导航到片段(导航架构组件)
Posted
技术标签:
【中文标题】在 FAB 单击时导航到片段(导航架构组件)【英文标题】:Navigate to fragment on FAB click (Navigation Architecture Components) 【发布时间】:2018-12-07 16:10:40 【问题描述】:我不知道如何使用新的导航架构组件从我的主屏幕(带有FloatingActionButton
附加到BottomAppBar
)导航到另一个屏幕没有应用栏。
当我单击晶圆厂时,我希望我的下一个屏幕(片段?)从右侧滑入。问题是我将BottomAppBar
放在哪里?如果我把它放在我的MainActivity
中,那么我会遇到FloatingActionButton
没有设置NavController
的问题。我也不能把我的BottomAppBar
放在我的片段中。我很茫然。
【问题讨论】:
【参考方案1】:今天遇到这个问题,发现有一个简单而优雅的解决方案。
val navController = findNavController(R.id.navHostFragment)
fabAdd.setOnClickListener
navController.navigate(R.id.yourFragment)
这负责导航。然后你必须控制BottomAppBar
在Activity
中的可见性。
【讨论】:
您不需要Navigation.setViewNavController(fabAdd, navController)
行 - 只有在您想使用 fabAdd.findNavController()
时才需要该行(并且,因为您已经引用了您的 NavController
,那是' t 你永远需要做的事情)。
如何更好地了解这个伟大的 API,但它的创造者!感谢 ianhanniballake 提供了很棒的图书馆和您的评论。我会把那条线去掉。
什么是 R.id.navHostFragment?
Type mismatch. Required: Fragment Found: Int
【参考方案2】:
您可以在MainActivity
中拥有您的BottomAppBar
,并在您的片段中访问您的FloatingActionButton
,如下所示
activity?.fab?.setOnClickListener
/*...*/
findNavController().navigate(R.id.action_firstFragment_to_secondFragment, mDataBundle)
您可以将BottomAppBar
隐藏在另一个活动中,如下所示
(activity as AppCompatActivity).supportActionBar?.hide()
确保您在返回上一个片段时.show()
BottomAppBar
【讨论】:
【参考方案3】:把它放在MainActivity中,setOnClickListener在activity的onStart()
中,就可以正常工作了。
override fun onStart()
super.onStart()
floatingActionButton.setOnClickListener
it.findNavController().navigate(R.id.yourFragment)
注意:此解决方案类似于 hack,更好的是在 Activity 准备好交互时遵循 Activity LifeCycle 并设置 OnClickListener。
Similar question [SOLVED]
【讨论】:
【参考方案4】:如果您出于某种原因想在开始时导航到某个片段(不是星号片段),并且您还必须为一项活动绘制图表,我的建议如下: 此方法将启动活动
companion object
const val REQUEST_OR_CONFIRM = "request_or_confirm"
const val IS_JUST_VIEW = "IS_JUST_VIEW"
const val MODEL = "model"
fun open(activity: Activity, isRequestOrConfirm: Boolean, isJustView: Boolean = false, model: DataModel? = null)
val intent = Intent(activity, HostActivity::class.java)
intent.putExtra(REQUEST_OR_CONFIRM, isRequestOrConfirm)
intent.putExtra(IS_JUST_VIEW, isJustView)
intent.putExtra(MODEL, model)
activity.startActivity(intent)
然后在 Host Activity 的 onCreate 方法中,首先决定使用哪个图,然后传递 Intent Extras 捆绑包,以便起始 Fragment 可以决定做什么:
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_purchase_nav)
if (intent.getBooleanExtra(REQUEST_OR_CONFIRM, true))
findNavController(R.id.nav_host_fragment).setGraph(R.navigation.nav_first_scenario, intent.extras)
else
findNavController(R.id.nav_host_fragment).setGraph(R.navigation.nav_second_scenario, intent.extras)
下面是你如何决定在开始片段中做什么:
if (arguments != null && arguments!!.getBoolean(HostActivity.IS_JUST_VIEW))
navigateToYourDestinationFrag(arguments!!.getParcelable<DataModel>(HostActivity.MODEL))
然后像往常一样导航:
private fun navigateToYourDestinationFrag(model: DataModel)
val action = StartFragmentDirections.actionStartFragmentToOtherFragment(model)
findNavController().navigate(action)
如果您想在一开始就跳转到第三个片段,您的图表可能看起来会是这样
PS:请确保您将处理第三个片段上的后退按钮,here 是一个解决方案
更新: 正如 EpicPandaForce 提到的,您还可以使用导航组件启动活动: 要做到这一点,首先将 Activity 添加到您现有的图表中,或者通过 + 图标(这对我不起作用)或通过手动添加 xml:
<activity
android:id="@+id/secondActivity"
tools:layout="@layout/activity_second"
android:name="com.amin.SecondActivity" >
</activity>
您还可以像在片段中一样添加参数并使用它们,使用 navArgs()
<activity
android:id="@+id/secondActivity"
tools:layout="@layout/activity_second"
android:name="com.amin.SecondActivity" >
<argument
android:name="testArgument"
app:argType="string"
android:defaultValue="helloWorld" />
</activity>
在 koltin 中,您将如何使用参数,首先声明 args 具有以您的活动命名的生成类的类型,在这种情况下,您的活动类顶部的 SecondActivityArgs:
val args: SecondActivityArgsby by navArgs()
然后你可以像这样使用它:
print(args.testArgument)
【讨论】:
我以为您不必再手动启动活动了,因为您可以使用ActivityDestination
。【参考方案5】:
这不会破坏 BottomAppBar。仅将此添加到 MainActivity,不要做任何其他事情
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
fabAdd.setOnClickListener
findNavController(navHostFragment).navigate(R.id.fab)
【讨论】:
以上是关于在 FAB 单击时导航到片段(导航架构组件)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用新的导航架构组件从扩展 BroadcastReceiver 的类导航到片段
使用导航从工具栏菜单项单击在片段之间传递数据 - Kotlin
如何使用导航架构组件创建 BottomSheetDialogFragment?