标签: android-jetpack-navigation

使用 Jetpack Compose 时如何更好地注入 ViewModel 对象?

我需要使用导航,并且我还需要在每个屏幕中使用SharedViewModel. 这是我尝试过的。

class MainActivity : ComponentActivity() {
    private lateinit var navController: NavHostController
    private val viewModel: SharedViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            navController = rememberNavController()
            NavGraph(
                navController = navController,
                sharedViewModel = sharedViewModel
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我将navController和传递sharedViewModel 给了NavGraph

fun NavGraph(
    navController: NavHostController,
    sharedViewModel: SharedViewModel
) {
    NavHost(
        navController = navController,
        startDestination = HomeScreen.route
    ) {
        composable(
            route = HomeScreen.route
        ) {
            HomeScreen(
                sharedViewModel = sharedViewModel
            )
        }
        composable(
            route …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack-navigation android-jetpack-compose dagger-hilt

2
推荐指数
1
解决办法
611
查看次数

androidx.navigation.fragment.NavHostFragment 无法从 xml 文件访问

我正在尝试使用带有底部导航视图的 androidx 导航。所以当我在 xml 文件中放置带有 android:name = "androidx.navigation.fragment.NavHostFragment" 的片段时,它给了我一个错误。我猜 xml 没有看到这个库或这个 Fragment

Here is xml file :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".weather.WeatherActivity"
        android:orientation="vertical"
        android:weightSum="10"
>
    <androidx.appcompat.widget.Toolbar
            android:id="@+id/w_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            android:theme="@style/ToolbarColoredBackArrow"
    />
        <fragment
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="9.6"
                android:id="@+id/nav_host_fragment"
                app:defaultNavHost = "true"
                app:navGraph = "@navigation/mobile_navigation"
                android:name="androidx.navigation.fragment.NavHostFragment"
                  />
        <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/bottom_nav"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.4"
                app:menu="@menu/bottom_nav"
        >

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

</LinearLayout>


Activity class:
class WeatherActivity : AppCompatActivity() {
    private lateinit var navController: NavController
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(com.example.upgrade.R.layout.activity_weather)
        val …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack androidx android-jetpack-navigation

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

我可以使用 safeargs 将可为空的数据类型作为参数发送吗?如果不是我该怎么办?

说我有 2 个片段。登录和主页。我将 Home 片段设置为以 userData 作为参数的全局目的地

在此处输入图片说明

如果用户还没有登录,那么它将从登录片段开始。登录并从服务器获取 userData 后,它将导航到 Home 并使用此代码传递 userData

 val home = AuthenticationFragmentDirections.actionGlobalHomeFragment(userData)
 Navigation.findNavController(view).navigate(home, navOptions)
Run Code Online (Sandbox Code Playgroud)

但问题是当用户已经登录并打开应用程序时。在这种情况下,他们将直接打开主页片段。我的应用程序因错误而崩溃

java.lang.IllegalArgumentException:缺少必需的参数“userData”并且没有 android:defaultValue

所以我假设我可以在像User? 这样的参数中设置可为空的数据类型,所以如果 Home 片段不是来自 Login 则不需要 userData

这里阅读后,我设置了这样的论点来实现User?

<argument
    android:name="userData"
    android:defaultValue="@null"
    app:argType="User"
    app:nullable="true" />
Run Code Online (Sandbox Code Playgroud)

但问题是,当我将用户数据从登录片段发送到家时,它说我有太多参数

我在gradle中使用这个

implementation "androidx.navigation:navigation-fragment-ktx:2.3.0-alpha04"
    implementation "androidx.navigation:navigation-ui-ktx:2.3.0-alpha04"
Run Code Online (Sandbox Code Playgroud)

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

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

Android 导航组件 - 从“任何地方”/基本片段导航?

我正在开发一个应用程序,它有一个古怪的噱头,可以在设备旋转时打开特定的片段。在实现 android 的导航组件之前,所需要的只是对当前活动的引用,并且可以在特定时刻向用户显示的任何内容之上执行手动片段事务。

但是在转到导航组件之后,我发现很难实现像上面的示例或(例如)如何从基本片段类显示简单对话框的通用内容。

有没有一种行之有效的方法来编写这种逻辑?

“SpecificFragment.kt”扩展“BaseFragment.kt”

BaseFragment.kt 可以承载所有通用逻辑来启动片段。通用片段逻辑仍然存在于 BaseFragment 中,但 BaseFragment(一个抽象类)不在导航图中(也不应该是(?)。因此,我不能从任何片段调用“BaseFragmentDirections.actionXXXX()”。

这个应该怎么写?

android android-jetpack-navigation

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

使用导航组件从后台删除片段

我有一个带有 navHost 片段的 PinCreateActivity 和 2 个片段 PinSetup 和 PinCreate 片段。

当 Activity 启动时,PinSetup 是默认片段,之后通过单击按钮导航到 PinCreate 片段。我想要的是来自 PinCreate 片段,当用户单击后退按钮时,不要像 PinCreateActivity 那样转到 PinSetup 并导航到后退堆栈。所以我想当我从 PinSetup 导航到 PinCreate 片段时,我必须从 backStack 中删除 PinSetup。我怎样才能做到这一点?

导航图.xml

<?xml version="1.0" encoding="utf-8"?>
<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/pin_create_nav_graph"
    app:startDestination="@id/pinSetupFragment">

    <fragment
        android:id="@+id/pinSetupFragment"
        android:name="com.example.ui.fragments.pin.PinSetupFragment"
        android:label="Create PIN"
        tools:layout="@layout/fragment_pin_setup" >
        <action
            android:id="@+id/action_pinSetupFragment_to_pinCreateFragment"
            app:destination="@id/pinCreateFragment" />
    </fragment>
    <fragment
        android:id="@+id/pinCreateFragment"
        android:name="com.example.ui.fragments.pin.PinCreateFragment"
        android:label="Your PIN"
        tools:layout="@layout/fragment_pin_create" />
</navigation>
Run Code Online (Sandbox Code Playgroud)

Pin创建活动

private lateinit var navController: NavController

 override fun onCreate(savedInstanceState: Bundle?) {
 
    ...
    navController = Navigation.findNavController(this, R.id.pin_create_host_fragment)


    // onClick
    navController.navigate(R.id.action_pinSetupFragment_to_pinCreateFragment)

 }
Run Code Online (Sandbox Code Playgroud)

android-fragments kotlin android-architecture-navigation android-jetpack-navigation android-navigation-graph

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

如何使用 Jetpack Compose 从单个目的地导航到多个目的地

总之,我想根据单击的项目导航到目的地。

在此输入图像描述

但问题是我创建这些项目的方式,这是我不知道如何隔离项目并为它们提供 onClick 函数的方式。

附言。我使用数据类和对象函数来制作项目;

data class MenuData(
    Val id: Int,
    Val title: String,
    val menuImageId: Int = 0
)
Run Code Online (Sandbox Code Playgroud)
object MenuModel {

    .....

    fun menuModelList(context: Context) = listOf(

        MenuData(
            id = 1,
            title = context.getString(R.string.menu_log),
            description = context.getString(R.string.menu_logText),
            menuImageId = R.drawable.menu_log
        ),
      .....
    )
}
Run Code Online (Sandbox Code Playgroud)


通常我所做的导航是(示例代码):

@Composable
fun WaysCard(
    waysInfo: WaysData,
    onWaysCardClick: (Int) -> Unit,
    modifier: Modifier = Modifier
) {
    Surface(
        shape = MaterialTheme.shapes.small,
        elevation = 10.dp,
        modifier = modifier
            .clickable { onWaysCardClick(waysInfo.id) }
    ) 
    ....
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我为可组合项提供了一个单击函数,并将数据类作为参数传递,因为通常这些项目是通用的,它们的大部分内容都以类似的方式排列。 …

android kotlin android-jetpack-navigation android-jetpack-compose jetpack-compose-navigation

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

带有导航组件和导航抽屉的单一活动应用程序

我想创建一个单一活动应用程序,为简单起见,它只包含以下屏幕:登陆、登录、注册、主页、个人资料。主页和个人资料屏幕仅在用户登录后才可见,并且属于导航抽屉。

不幸的是,我想到的是用 nav_graph_1 创建一个活动,其中包含以下目的地:登陆、登录、注册。然后使用 nav_graph_2(主页和个人资料目的地)创建另一个活动,其中将包含导航抽屉的所有设置:例如setupActionBarWithNavController,带有 nav_graph_2 和抽屉的 appBarConfiguration。

是否可以在单个活动应用程序中实现上述内容以及如何实现?

android navigation-drawer android-architecture-navigation android-jetpack-navigation android-navigation-graph

0
推荐指数
1
解决办法
690
查看次数

Android:没有通过 app:startDestination 为 xxx:id/nav_graph 定义起始目的地

在 nav_graph 中,即使我已经使用过,我也会收到警告

在此处输入图片说明

项目级gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.3.72'
    repositories {
        google()
        jcenter()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        def nav_version = "2.3.0-beta01"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

allprojects {
    repositories {
        google()
        jcenter()

    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
Run Code Online (Sandbox Code Playgroud)

应用级gradle:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "androidx.navigation.safeargs.kotlin"

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.demo.sample" …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack android-jetpack-navigation android-navigation-graph

-2
推荐指数
1
解决办法
4345
查看次数