基本上,我有以下导航图:
我想在到达后立即将导航图中的起点更改为片段2
(以防止在按下后退按钮时返回到片段1
,就像启动屏幕一样)。
这是我的代码:
navGraph = navController.getGraph();
navGraph.setStartDestination(R.id.fragment2);
navController.setGraph(navGraph);
但是,显然它不工作,它回到片段1
后按后退按钮。
我做错了吗?还有其他解决办法吗?
在主要活动中。kt
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.booking_navigation)
if (isTrue){
graph.startDestination = R.id.DetailsFragment
}else {
graph.startDestination = R.id.OtherDetailsFragment
}
val navController = navHostFragment.navController
navController.setGraph(graph, intent.extras)
从导航图中删除startDestination。xml
?xml version="1.0" encoding="utf-8"?>
<!-- app:startDestination="@id/oneFragment" -->
<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/navigation_main">
<fragment
android:id="@+id/DetailFragment"
android:name="DetailFragment"
android:label="fragment_detail"
tools:layout="@layout/fragment_detail"/>
<fragment
android:id="@+id/OtherDetailFragment"
android:name="OtherDetailFragment"
android:label="fragment_other_detail"
tools:layout="@layout/fragment_other_detail"/>
</navigation>
我找到了一个解决方案,但它很难看。我想这是alpha库的预期,但我希望谷歌能简化/修复这个问题,因为这是一个非常流行的导航模式。
亚历克西的解决方案对我不起作用。我的问题是,我的操作栏上显示了向上箭头:
NavigationUI。setupActionBarWithNavController(这是navController)
如果我按照Alexey的建议去做,我的新起始片段仍然有一个箭头指向我的初始起始片段。如果我按下那个向上箭头,我的应用程序就会重新启动,转换到自身(新的开始片段)
以下是我想要的代码:
下面是实现这一点的代码。在我的活动的onCreate中:
// Setup the toolbar
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(false)
// Configure the navigation
val navHost = nav_host_fragment as NavHostFragment
graph = navHost.navController
.navInflater.inflate(R.navigation.nav_graph)
graph.startDestination = R.id.welcomeFragment
// This seems to be a magical command. Not sure why it's needed :(
navHost.navController.graph = graph
NavigationUI.setupActionBarWithNavController(this, navHost.navController)
并且还:
fun makeHomeStart(){
graph.startDestination = R.id.homeFragment
}
然后根据Alexey的建议,在片段#1的OnActivity Created中:
override fun onActivityCreated(savedInstanceState: Bundle?) {
...
// Check for user authentication
if(sharedViewModel.isUserAuthenticated()) {
(activity as MainActivity).makeHomeStart() //<---- THIS is the key
val navOptions = NavOptions.Builder()
.setPopUpTo(R.id.welcomeFragment, true)
.build()
navController.navigate(R.id.action_welcomeFragment_to_homeFragment,null,navOptions)
} else {
navController.navigate(R.id.action_welcomeFragment_to_loginFragment)
}
}
关键代码是:(活动作为MainActivity)。makeHomeStart()
,它只是在活动中运行一个方法来更改图形startDestination。我可以把它清理干净,把它变成一个界面,但我会等待谷歌,希望他们能改进整个html" target="_blank">过程。对我来说,方法“setPoputto”的命名似乎很糟糕,而且你对从图中删除的片段进行命名并不直观。我也很奇怪,他们在导航选项上做了这些改变。我认为导航选项只与它们所连接的导航操作有关。
我甚至不知道navHost是什么。导航控制器。graph=graph有,但没有它,向上箭头返回:(
我正在使用导航1.0.0-alpha06。
当你有这样的导航图:
<fragment
android:id="@+id/firstFragment"
android:name="com.appname.package.FirstFragment" >
<action
android:id="@+id/action_firstFragment_to_secondFragment"
app:destination="@id/secondFragment" />
</fragment>
<fragment
android:id="@+id/secondFragment"
android:name="com.appname.package.SecondFragment"/>
如果要导航到第二个片段并使其成为图形的根,请指定下一个NavOptions
:
NavOptions navOptions = new NavOptions.Builder()
.setPopUpTo(R.id.firstFragment, true)
.build();
并将其用于导航:
Navigation.findNavController(view).navigate(R.id.action_firstFragment_to_secondFragment, bundle, navOptions);
setPoputo(int destinationId,含布尔值)
-导航前弹出到给定的目的地。这会从后堆栈中弹出所有不匹配的目标,直到找到该目标。
destinationId
-要弹出的目的地,清除所有中间的目的地。
包含
-也可以从后栈弹出给定的目标。
<fragment
android:id="@+id/firstFragment"
android:name="com.appname.package.FirstFragment" >
<action
android:id="@+id/action_firstFragment_to_secondFragment"
app:destination="@id/secondFragment"
app:popUpTo="@+id/firstFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/secondFragment"
android:name="com.appname.package.SecondFragment"/>
然后在你的代码上:
findNavController(fragment).navigate(
FirstFragmentDirections.actionFirstFragmentToSecondFragment())
弃用:已弃用NavOptions
中操作和关联API的clearTask
属性。
资料来源:https://developer.android.com/jetpack/docs/release-notes
如果您想将根片段更改为片段2
(例如,按下片段2
上的后退按钮后,您将退出应用程序),您应该将下一个属性添加到操作
或目的地
:
app:clearTask="true"
从另一个角度来看:
<fragment
android:id="@+id/firstFragment"
android:name="com.appname.package.FirstFragment"
android:label="fragment_first" >
<action
android:id="@+id/action_firstFragment_to_secondFragment"
app:destination="@id/secondFragment"
app:clearTask="true" />
</fragment>
<fragment
android:id="@+id/secondFragment"
android:name="com.appname.package.SecondFragment"
android:label="fragment_second"/>
我已经添加了app: clearWork="true"
到操作。
现在,当您执行从片段1
到片段2
的导航时,使用下一个代码:
Navigation.findNavController(view)
.navigate(R.id.action_firstFragment_to_secondFragment);
问题内容: 我有一个带有标题的导航栏。当我双击文本以将其重命名时,它实际上说这是一个导航项,所以可能就是这样。 我正在尝试使用代码来更改文本,例如: 那显然不是我的代码,只是显示了它是如何工作的。 因此,每当我按下按钮时,我都希望标题更改。 问题答案: 您可以通过更改显示的视图控制器的标题来更改标题: 通常,这是在视图控制器上加载视图时完成的: 但是,这仅在将视图控制器嵌入UINavigation
我正在使用底部导航视图并希望以编程方式更改项目。有5个项目,当我设置第四个项目时,第一个项目仍然处于活动状态。
问题内容: 如何以编程方式更改ActionBar中的MenuItem图标?我尝试使用 但这不起作用。这是我的代码: 主要活动 main.xml activity_main 这是我跑步后遇到的例外: 问题答案: 您不能在onCreate()的菜单项上使用findViewById(),因为菜单布局尚未膨胀。您可以创建一个全局Menu变量,并在onCreateOptionsMenu()中对其进行初始化,
问题内容: 我使用了Android Studio中提供的Navigation Drawer模板。在我的活动布局中,我有以下代码: 我需要以编程方式更改面板的宽度。我认为更改它的正确区域是: 但是我不明白如何实现我的目标。 / 更新 / 抽屉面板的图标未显示在操作栏中 那就是selectItem方法 问题答案: 基于从Navigation Drawer模板生成的代码,可以通过将代码添加到Naviga
我尝试通过主题或编程方式更改导航栏的颜色。 以下是我到目前为止所做的尝试: 在样式v21中: 以编程方式: 问题是:它在Nexus设备(Android 7.1.1)上运行得很好,但在LG Q6上运行得不好(同样适用于Android 7.1.1)。 我认为有办法做到这一点(因为Youtube应用程序有自己的导航栏颜色),但我不知道怎么做。 我也尝试了几乎所有的东西,这里,这里,这里和这里,都没有成功
问题内容: 描述性示例: 登录屏幕,用户点击“登录”按钮,执行请求,UI显示等待指示器,然后在成功响应后,我想自动将用户导航到下一个屏幕。 如何在SwiftUI中实现这种自动转换? 问题答案: 成功登录后,可以使用登录视图替换下一个视图。例如: 您应该在数据模型中处理登录过程,并使用绑定(例如)传递到视图。 注意: 在Xcode中 11.0版测试4 ,以符合协议 “BindableObject”