标签: android-jetpack-navigation

如何隐藏某些片段中的底部导航栏?

我有一个带有 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

8
推荐指数
1
解决办法
3518
查看次数

Android 导航组件片段过渡具有白色背景

我正在使用 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

8
推荐指数
1
解决办法
1373
查看次数

导航组件:IllegalStateException 片段与片段管理器无关

我正在使用导航组件版本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

8
推荐指数
3
解决办法
5973
查看次数

与来自 jetpack 的 Android 导航一起使用时,始终会重新创建片段

我正面临着使用 Android 导航组件重新创建片段的问题。我已经集成了底部导航并将其与 android 导航组件结合起来。因此,每次单击底部栏上的选项卡时,都会重新创建片段并且不会保留旧状态。

即使我转到其他选项卡并返回,我也想保留片段的状态。我没有在任何地方找到任何解决方案。

除了底部导航,我使用navController.navigate()方法在不同的片段之间导航。

android android-fragments android-jetpack android-architecture-navigation android-jetpack-navigation

8
推荐指数
1
解决办法
2933
查看次数

如何使用导航组件切换到不同返回堆栈中的其他片段?

我有 3 个底部导航选项卡,称为Home, Dashboard, Profile.

  • Home,我有Fragment1Fragment2
  • Dashboard,我有Fragment3Fragment4
  • 在 中Profile,我有MyProfileEditProfile

现在,在 中Fragment2,一个按钮changeAvatar可以EditProfile在 stack 中打开Profile。因为EditProfile应该在 tab 中Profile,所以如果我不想包含EditProfilenavGraphof 中Home,我该如何实现这种行为?

navigation android android-architecture-navigation android-jetpack-navigation

8
推荐指数
2
解决办法
412
查看次数

从共享表启动应用程序时导航至特定片段

我在我的应用程序中使用具有一个活动和两个片段的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

7
推荐指数
1
解决办法
136
查看次数

Jetpack compose NavHost 防止重组屏幕

正如你所看到的,这就是我使用 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

7
推荐指数
1
解决办法
3207
查看次数

如何在 Jetpack Compose 中保存和恢复导航状态?

我想导航到另一个屏幕,但我想保存当前状态,然后恢复它。我尝试按照底部导航文档中的描述进行操作:

navController.navigate(Screen.CameraScreen.route) {
        popUpTo(navController.graph.id) {
            saveState = true
        }
    restoreState = true
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用。

android android-jetpack-navigation android-jetpack-compose

7
推荐指数
1
解决办法
9256
查看次数

具有不同导航图的相同片段(由 hiltNavGraphViewModels 提供)

我的应用程序遵循单一活动模式。我的 MainActivity 有一个包含 4 个片段的底部导航。

主导航图

nav_homenav_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

7
推荐指数
1
解决办法
560
查看次数

Android:如何防止 Scaffolds 顶部应用栏在 Jetpack Compose Navigation 中重绘?

当在两个屏幕之间导航时,每个屏幕都有一个带有 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

7
推荐指数
1
解决办法
1272
查看次数