我有一个带有 navGraph 的活动和一个带有 2 个菜单项的底部导航栏。我的问题是我的底部导航栏到处出现,detailFragment、aboutFragment、signInFragment等等。
val navController = this.findNavController(R.id.myNavHostFragment)
val appBarConfiguration = AppBarConfiguration.Builder(
R.id.contactsFragment,
R.id.profileFragment
).build()
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
NavigationUI.setupWithNavController(navView, navController)
Run Code Online (Sandbox Code Playgroud)
我如何限制它只显示在我的菜单项上的 2 个片段上?
这就是我解决它的方法
navController.addOnDestinationChangedListener{ _, nd: NavDestination, _->
if(nd.id == R.id.contactsFragment || nd.id == R.id.profileFragment){
navView.visibility = View.VISIBLE
}else{
navView.visibility = View.GONE
}
Run Code Online (Sandbox Code Playgroud) kotlin android-jetpack android-bottomappbar android-jetpack-navigation
我正在使用 Jetpack Navigation 库并且在片段转换方面遇到问题,无论是淡入淡出还是幻灯片动画,它始终具有白色背景而不是前一个屏幕内容。
片段 A -> 片段 B,当动画正在运行而不是将背景视为片段 A 时,它是白色背景。
导航
<fragment
android:id="@+id/nav_page"
android:name="my.fragmenta"
tools:layout="@layout/fragment_a">
<action
android:id="@+id/action_to_b"
app:destination="@id/nav_b"
app:enterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"/>
</fragment>
Run Code Online (Sandbox Code Playgroud)
活动方式
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@color/statusBarColor</item>
</style>
Run Code Online (Sandbox Code Playgroud)
动画文件
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYDelta="100%p"
android:toYDelta="0"
android:duration="@android:integer/config_longAnimTime" />
Run Code Online (Sandbox Code Playgroud)
和
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYDelta="0"
android:toYDelta="100%p"
android:duration="@android:integer/config_longAnimTime" />
Run Code Online (Sandbox Code Playgroud)
任何人都知道如何解决它?
android android-fragments android-navigation android-jetpack android-jetpack-navigation
我正在使用导航组件版本2.1.0-rc01,我使用 3 个屏幕之间来回导航
Navigation.findNavController(it).navigate(R.id.action_participants)
第二次通过相同的屏幕后,我可以看到第二个片段,但我收到一个异常。我在 FragmentManager 上启用了日志,似乎没有附加相同片段的不同实例,导致错误
关于为什么导航组件创建另一个未附加的片段实例的任何想法?获取附加片段的任何解决方法?
2019-08-15 16:59:30.895 30041-30041/com.app.debug D/FragmentManager: mName=3-2131361912 mIndex=-1 mCommitted=false
2019-08-15 16:59:30.895 30041-30041/com.app.debug D/FragmentManager: mEnterAnim=#7f01001e mExitAnim=#7f01001f
2019-08-15 16:59:30.896 30041-30041/com.app.debug D/FragmentManager: mPopEnterAnim=#7f010020 mPopExitAnim=#7f010021
2019-08-15 16:59:30.896 30041-30041/com.app.debug D/FragmentManager: Operations:
2019-08-15 16:59:30.896 30041-30041/com.app.debug D/FragmentManager: Op #0: REPLACE StaffBookingDetailsFragment{82e8301 (97f79b28-d8c1-432a-9e1c-3a781dd42434) id=0x7f0a01c5}
2019-08-15 16:59:30.896 30041-30041/com.app.debug D/FragmentManager: enterAnim=#7f01001e exitAnim=#7f01001f
2019-08-15 16:59:30.896 30041-30041/com.app.debug D/FragmentManager: popEnterAnim=#7f010020 popExitAnim=#7f010021
2019-08-15 16:59:30.896 30041-30041/com.app.debug D/FragmentManager: Op #1: SET_PRIMARY_NAV StaffBookingDetailsFragment{82e8301 (97f79b28-d8c1-432a-9e1c-3a781dd42434) id=0x7f0a01c5}
2019-08-15 16:59:30.897 30041-30041/com.app.debug D/FragmentManager: enterAnim=#7f01001e exitAnim=#7f01001f
2019-08-15 16:59:30.897 30041-30041/com.app.debug D/FragmentManager: popEnterAnim=#7f010020 popExitAnim=#7f010021
2019-08-15 16:59:31.935 …Run Code Online (Sandbox Code Playgroud) android android-fragments android-jetpack android-architecture-navigation android-jetpack-navigation
我正面临着使用 Android 导航组件重新创建片段的问题。我已经集成了底部导航并将其与 android 导航组件结合起来。因此,每次单击底部栏上的选项卡时,都会重新创建片段并且不会保留旧状态。
即使我转到其他选项卡并返回,我也想保留片段的状态。我没有在任何地方找到任何解决方案。
除了底部导航,我使用navController.navigate()方法在不同的片段之间导航。
android android-fragments android-jetpack android-architecture-navigation android-jetpack-navigation
我有 3 个底部导航选项卡,称为Home, Dashboard, Profile.
Home,我有Fragment1和Fragment2,Dashboard,我有Fragment3和Fragment4Profile,我有MyProfile和EditProfile。现在,在 中Fragment2,一个按钮changeAvatar可以EditProfile在 stack 中打开Profile。因为EditProfile应该在 tab 中Profile,所以如果我不想包含EditProfile到navGraphof 中Home,我该如何实现这种行为?
navigation android android-architecture-navigation android-jetpack-navigation
我在我的应用程序中使用具有一个活动和两个片段的Jetpack Navigation(片段A也是家庭片段,而片段B可以从片段A导航)。
有一个intent-filter添加到MainActivity如下所示它可以接受纯文本。
<activity android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="@string/text_mime_type_text_plain"/>
</intent-filter>
</activity>
Run Code Online (Sandbox Code Playgroud)
当用户选择从Android sharesheet我的应用程序,最终目标是通过从接收到的意图的片段B目前数据,我接收到意图在片段A(家庭片段),然后使用NavController导航到片段B使用下面的代码。
private fun checkReceivedIntent() {
val receivedUrlIntent = activity?.intent
val intentAction = receivedUrlIntent?.action
val intentType = receivedUrlIntent?.type
if (intentAction == Intent.ACTION_SEND && intentType != null) {
if (intentType == getString(R.string.text_mime_type_text_plain) ) {
val receivedText = receivedUrlIntent.getStringExtra(Intent.EXTRA_TEXT)
val action = FragmentADirections.actionFragmentAToFragmentB(receivedText)
findNavController().navigate(action)
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题在于,当打开片段B时,按下工具栏的后退按钮或后退箭头(即使多次按下),也不会出现片段A,并且片段B会继续出现。
我不知道我在想什么。当用户从另一个应用程序内的共享表打开该应用程序时,这是打开特定片段的正确方法吗?
编辑
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> …Run Code Online (Sandbox Code Playgroud) android android-fragments android-jetpack android-jetpack-navigation
正如你所看到的,这就是我使用 MaterialBottomNavigation 实现 NavHost 的方式,我在消息和提要屏幕上都有很多项目,当我在这两个屏幕之间导航时,它们会自动重新组合,但我不想,因为那里有太多数据,它会闪烁并且 fps 下降导航时低于 10,我尝试在 NavHost 之前初始化数据 viewModel,但结果仍然相同,有没有办法一次性组合屏幕并在 viewModels 数据更新时更新它们?
@Composable
private fun MainScreenNavigationConfigurations(
navController: NavHostController,
messagesViewModel: MessagesViewModel = viewModel(),
feedsViewModel: FeedsViewModel = viewModel(),
) {
val messages: List<Message> by messagesViewModel.messages.observeAsState(listOf())
val feeds: List<Feed> by feedsViewModel.messages.observeAsState(listOf())
NavHost(
navController = navController,
startDestination = "Messages"
) {
composable("Messages") {
Messages(navController, messages)
}
composable("Feeds") { Feeds(navController, feeds) }
}
}
Run Code Online (Sandbox Code Playgroud) android kotlin android-jetpack android-jetpack-navigation android-jetpack-compose
我想导航到另一个屏幕,但我想保存当前状态,然后恢复它。我尝试按照底部导航文档中的描述进行操作:
navController.navigate(Screen.CameraScreen.route) {
popUpTo(navController.graph.id) {
saveState = true
}
restoreState = true
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用。
我的应用程序遵循单一活动模式。我的 MainActivity 有一个包含 4 个片段的底部导航。
nav_home和nav_video具有相同的片段,因此我希望 HomeViewModel 和 VideoViewModel 将其状态保留在这些图中。正如你在下面看到的。
nav_home.xml
nav_video.xml
在我的片段中,我使用hiltNavGraphViewModels扩展来保持视图模型状态。
@AndroidEntryPoint
class CourseDetailFragment : Fragment(R.layout.fragment_course_detail),
LoadingDelegate by LoadingDelegateImpl(), NavigationDelegate by NavigationDelegateImpl() {
private val binding by viewBinding(FragmentCourseDetailBinding::bind)
private val viewModel: CourseDetailViewModel by viewModels()
private val categoryViewModel: CategoryViewModel by hiltNavGraphViewModels(R.id.nav_video)
private val homeViewModel: HomeViewModel by hiltNavGraphViewModels(R.id.nav_home)
Run Code Online (Sandbox Code Playgroud)
如果我从家里到达这个片段,categoryViewModel 会抛出异常,并显示:
java.lang.IllegalArgumentException: NavController 的返回堆栈上没有 ID 为 2131362218 的目标。当前目的地是 Destination(com.example.app:id/courseDetailFragment) label=CourseDetailFragment class=com.example.app.ui.course.CourseDetailFragment
另一方面,如果我从视频中到达这个片段,homeViewModel 会抛出相同的异常。
任何帮助将受到热烈欢迎。谢谢。
navigation android android-fragments android-jetpack-navigation dagger-hilt
当在两个屏幕之间导航时,每个屏幕都有一个带有 TopAppBar 的脚手架,TopAppBar 会以动画方式退出 UI 并返回。(在我的示例中短暂的白色闪烁,就像按钮动画一样)
我想这种行为是预期的,因为 compose 无法知道,这两者应该被视为相同。
有没有什么方法可以防止这种行为,而不将标题状态提升到 MainNavigation 可组合项,以便仅在导航上重绘标题?我认为在 flutter 中几乎所有小部件都有一个名为“key”的属性,jetpack compose 中也有类似的属性吗?
对于这个小例子来说,这很好,但是当有一个更复杂的导航图时,我担心 MainNavigation 会因属于其他地方的语义而过载,例如加载数据以显示项目名称......
代码
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
UnwelcomeNavAnimationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
MainNavigation()
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "screen1") {
composable("screen1") {
Scaffold( …Run Code Online (Sandbox Code Playgroud) android android-architecture-navigation android-jetpack-navigation android-jetpack-compose android-jetpack-compose-material3