sty*_*972 10 android android-architecture-navigation androidx android-deep-link
我正在尝试使用深层链接进行跨模块用户导航,并且我需要传递一些参数。由于它位于另一个模块中,因此我无权访问id,因此所有navigate(@IdRes int resId, ...)方法都不适用。
使用 Android Jetpack 的导航组件导航具有键值对的Uri深层链接的最佳方法是什么?Bundle
navigation.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"
android:id="@+id/navGraph"
app:startDestination="@id/feature_one">
<include app:graph="@navigation/feature_one" />
<include app:graph="@navigation/feature_two />
</navigation>
Run Code Online (Sandbox Code Playgroud)
feature_one.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"
android:id="@+id/feature_one"
app:startDestination="@id/oneFragment">
<fragment
android:id="@+id/oneFragment"
android:name="my.app.OneFragment"
android:label="OneFragment" />
</navigation>
Run Code Online (Sandbox Code Playgroud)
feature_two.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"
android:id="@+id/feature_two"
app:startDestination="@id/twoFragment">
<fragment
android:id="@+id/twoFragment"
android:name="my.app.TwoFragment"
android:label="TwoFragment">
<deepLink app:uri="myapp://my.app/?myId={myId}" />
<argument android:name="myId" app:argType="long" />
</fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)
OneFragment.kt(:一个模块)
val bundle = bundleOf("myId" to 123L)
val request = NavDeepLinkRequest.Builder
.fromUri("myapp://my.app?myId={myId}")
.build()
// No place to bundle the args
findNavController().navigate(
request,
navOptions
)
Run Code Online (Sandbox Code Playgroud)
TwoFragment.kt(:两个模块)
private val args: TwoFragmentArgs by navArgs()
...
val myId: Long = args.myId // never set, so how?
Run Code Online (Sandbox Code Playgroud)
tldr:仔细检查确保在创建请求时正确编码所有内容,特别是如果您使用包含多个单词、空格或特殊字符的参数,则需要使用已经为您编码的 Uri.Builder 方法或事先自己对它们进行编码
您的 xml 定义正确,问题在于您如何构建 URI。
我做的几乎和你一样,但是使用
val myId = 123L
val uri = Uri.Builder().path("myapp://my.app/$myId")
.build()
val request = NavDeepLinkRequest.Builder
.fromUri(uri)
.build()
findNavController().navigate(request)
Run Code Online (Sandbox Code Playgroud)
并且深层链接无法匹配此 URI,并给出此异常
java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{...
我可以通过改变 URI 的构建方式来解决这个问题
像这样构建它
val myId = 123L
val uri = Uri.Builder().scheme("myapp")
.authority("my.app")
.path("/$myId")
.build()
val request = NavDeepLinkRequest.Builder
.fromUri(uri)
.build()
findNavController().navigate(request)
Run Code Online (Sandbox Code Playgroud)
或像这样(如@SUR4IDE答案)
val myId = 123L
val correctyEncodedId = URLEncoder.encode(myId, "utf-8")
val request = NavDeepLinkRequest.Builder
.fromUri(Uri.parse("myapp://my.app/$correctyEncodedId"))
.build()
findNavController().navigate(request)
Run Code Online (Sandbox Code Playgroud)
这两种方法都避免了路径 String 的编码有些不同的问题,特别是如果参数具有在 URI 中以不同方式编码的空格或特殊字符,并且与我的场景中feature_two.xml中定义的深层链接不匹配。URI 字符串被编码为"myapp%3A//my.app/123",这种:编码差异导致匹配不起作用,所以就像我没有使用定义的深层链接一样。
当匹配成功时,导航类会将 URI 中的参数与 .xml 中定义的参数进行匹配(它们的名称必须与您所做的完全相同),并使用它们作为参数创建一个 Bundle 并将其传递给它将导航到的片段或活动。
| 归档时间: |
|
| 查看次数: |
1924 次 |
| 最近记录: |