This library goes through your navigation files, pulls out information about deep links, generates code and puts it in a separate module navigation_deep_links
.
buildscript {
dependencies {
...
classpath("family.amma:deeplinks-gradle-plugin:<last_version>")
// not necessary, but handy for working with taking arguments
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5")
}
}
plugins {
...
id("family.amma.deepLinks")
id("androidx.navigation.safeargs.kotlin")
}
The module automatically generated after the build, but for manual launch :generateDeepLinks
include(
...,
":navigation-deep-links"
)
dependencies {
implementation(project(":navigation-deep-links"))
}
If you want additional behavior, you can config the flags.
configure<family.amma.deep_link.gradle_plugin.DeepLinksPluginExtension> {
generateByDestinations = true // Generation of a separate file with deep links for each destination.
generateUriHierarchy = false // Generating a hierarchy of deep links based on their url.
generateAdditionalInfo = false // Generation of additional information for all types of generation: names, protocol, host and path segments.
}
We declare a deep link and (optional) arguments to it
<fragment
android:id="@+id/secondFragment"
android:name="family.amma.module_b.SecondFragment"
android:label="SecondFragment"
tools:layout="@layout/fragment_second">
<argument
android:name="isEditMode"
app:argType="boolean" />
<argument
android:name="id"
app:argType="integer"
android:defaultValue="10" />
<deepLink
android:id="@+id/barFoo"
app:uri="http://www.example.com/users/{id}?isEditMode={isEditMode}" />
</fragment>
public sealed class SecondFragmentDeepLink : GeneratedDeepLink {
public data class BarFoo(
public val id: Int = 10,
public val isEditMode: Boolean
) : SecondFragmentDeepLink() {
public override val uri: String =
"""http://www.example.com/users/${id}?isEditMode=${isEditMode}"""
}
}
If we activate the generateAdditionalInfo
flag:
public sealed class SecondFragmentDeepLink : GeneratedDeepLink {
public data class BarFoo(
public val id: Int = 10,
public val isEditMode: Boolean
) : SecondFragmentDeepLink() {
public override val uri: String =
"""http://www.example.com/users/${id}?isEditMode=${isEditMode}"""
public companion object {
public const val protocol: String = "http"
public const val host: String = "www.example.com"
public val pathSegments: List<String> = listOf("users")
}
}
}
If we activate the generateAdditionalInfo
flag:
public sealed class ModuleB : GeneratedDeepLink {
public sealed class Http : ModuleB() {
public sealed class WwwExampleCom : Http() {
public data class UsersDeepLink(
public val id: Int = 10,
public val isEditMode: Boolean
) : WwwExampleCom() {
public override val uri: String =
"""http://www.example.com/users/${id}?isEditMode=${isEditMode}"""
}
}
}
}
By analogy above for the flag generateAdditionalInfo
.
public sealed class ModuleB : GeneratedDeepLink {
public sealed class Http : ModuleB() {
public companion object {
public const val name: String = "http"
}
public sealed class WwwExampleCom : Http() {
public companion object {
public const val name: String = "www.example.com"
}
public data class UsersDeepLink(
public val id: Int = 10,
public val isEditMode: Boolean
) : WwwExampleCom() {
public override val uri: String =
"""http://www.example.com/users/${id}?isEditMode=${isEditMode}"""
public companion object {
public const val protocol: String = "http"
public const val host: String = "www.example.com"
public val pathSegments: List<String> = listOf("users")
}
}
}
}
}
class FirstFragment : Fragment(R.layout.fragment_first) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.button).setOnClickListener {
// deep links args
val id = Random.nextInt()
val isEditMode = Random.nextBoolean()
// the same deep links - by name and hierarchical
val deepLink = if (Random.nextBoolean()) {
SecondFragmentDeepLink.BarFoo(id, isEditMode)
} else {
ModuleB.Http.WwwExampleCom.UsersDeepLink(id, isEditMode)
}
findNavController().navigate(deepLink.toNavDeepLinkRequest())
}
}
}
private inline fun GeneratedDeepLink.toNavDeepLinkRequest(block: NavDeepLinkRequest.Builder.() -> Unit = {}) =
NavDeepLinkRequest.Builder.fromUri(Uri.parse(this.uri)).also(block).build()
class SecondFragment : Fragment(R.layout.fragment_second) {
private val args by navArgs<SecondFragmentArgs>()
@SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<TextView>(R.id.argsTextView).text = "Args: id = ${args.id}, isEditMode = ${args.isEditMode}"
}
}