Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/veepee-oss/link-router
Android routing library
https://github.com/veepee-oss/link-router
Last synced: 3 months ago
JSON representation
Android routing library
- Host: GitHub
- URL: https://github.com/veepee-oss/link-router
- Owner: veepee-oss
- License: isc
- Created: 2021-07-22T08:22:19.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-07-04T14:00:01.000Z (4 months ago)
- Last Synced: 2024-07-27T09:34:50.829Z (4 months ago)
- Language: Kotlin
- Size: 571 KB
- Stars: 44
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: contributing.md
- License: LICENSE
Awesome Lists containing this project
- awesome-list - veepee-oss/link-router - Android routing library (Kotlin)
README
# link-router
This library contains the basic infrastructure for routing DeepLinks, Activities, Fragments and Composables within a multi-module application
in a way that a feature module does not need to explicitly depend of another.### Usage
The basic concept is the same for all routing, at the app startup we register all Deeplink, Activities, Fragments and Compose mappers
and in a separated module (like :routes) we share basic "links" that work as indirections to the real implementations.### Abstractions
Activities, Fragments and Composables have similar abstractions, so if you know how to route Activities, you know how to route Fragments and Composables.
| Activity | Fragment | Composable |
|:--------------------:|:--------------------:|:--------------------:|
| ActivityName | FragmentName | ComposableName |
| ActivityLink | FragmentLink | ComposableLink |
| ActivityNameMapper | FragmentNameMapper | ComposableNameMapper |
| ParcelableParameter | ParcelableParameter | ComposableParameter |
| ActivityLinkRouter | FragmentLinkRouter | ComposableLinkRouter |### Activities
To make it possible to route your Activity into other modules we need to implement `ActivityName`,
`ActivityLink` and `ActivityNameMapper` that reflects your needs.- `ActivityName` acts as key when routing to your Activity # lives in a shared module
- `ActivityLink` binds the `ActivityName` with parameters we want to pass to that Activity and # lives in a shared module
- `ActivityNameMapper` maps the `ActivityName` into an Activity class. # on your feature module#### Things we need to place in a shared module
The `ActivityLink` and `ActivityName` are used to route, so the client module needs to have access to that implementation.
You can place it in a `:routes` module or in any other shared module that suits your needs (`:mydomain:routes`, maybe?).````kotlin
object MyActivityName : ActivityName
````````kotlin
class MyActivityLink(
override val parameter: MyActivityParameter
) : ActivityLink {override val activityName: MyActivityName = MyActivityName
}@Parcelize
data class MyActivityParameter(val data: String) : ParcelableParameter````
#### Things that we keep inside our feature modules
With that `ActivityName` we can implement an `ActivityNameMapper` into your feature module.```kotlin
object MyActivityNameMapper : ActivityNameMapper {
override val supportedNames: Array = arrayOf(MyActivityName)override fun map(activityLink: ActivityLink): Class {
return MyActivityName::class.java
}
}```
#### Pro tip
If your module has multiple activities you can use an enum for your `ActivityName`
and only one implementation of `ActivityNameMapper`.
````kotlin
enum class MyFeatureModuleActivitiesNames : ActivityName {
MyActivityName,
MyOtherActivityName
}
````and
```kotlin
object MyFeatureModuleActivityNameMapper :
ActivityNameMapper {
override val supportedNames: Array = MyFeatureModuleActivitiesNames.values()override fun map(activityLink: ActivityLink): Class {
return when (activityLink.activityName) {
MyFeatureModuleActivitiesNames.MyActivityName -> MyActivity::class.java
MyFeatureModuleActivitiesNames.MyOtherActivityName -> MyOtherActivity::class.java
}
}
}```
### DeepLinks
The handling of DeepLinks is a bit different from the other components that we support.
We don't define a `DeepLinkName` as DeepLink usually come in a String format and parsing/matching rules that are application specific.
To each DeepLink we only need an implementation of `DeepLinkMapper`,
where we describe for which schemes that DeepLink is supported, what is the DeepLink authority and
what stack of Activities should be created.```kotlin
object MyDeepLinkMapper : DeepLinkMapper {
override val supportedSchemes: Array = arrayOf(Schemes.publicAppSchemes)
override val supportedAuthority: String = "my_authority"override fun stack(deepLink: UriDeepLink): Array> {
return arrayOf(
ExternalDeepLinkRouterActivityLink(deepLink.parameter)
)
}override fun canHandle(deepLink: DeepLink): Boolean {
return super.canHandle(deepLink) && deepLink is UriDeepLink
}
}```
Since you are in charge of defining what parameters to pass to each `ActivityLink`,
you can use it to define your app state and navigate internally to a given
Fragment or Composable back stack that you see convenient to your business logic.### Compose
Define your `ComposeName`, `ComposableLink`, `ComposableLinkMapper` and set in the root of your
Composable tree a `LinkRouterContainer` with an instance of `LinkRouter` reference configured by you.
With that you can call `ComposableFor` with a `ComposableLink` and optionally a `Modifier`.```kotlin
LinkRouterContainer(router = router) {
ComposableFor(
FeatureBComposableLink("Some text"),
Modifier
)
}
```### Runtime registration
You can use the `Application.create()` method or Googles StartUp library to register your mappers.
Use `RouterBuilder` to register `ActivityNameMapper`s, `FragmentNameMapper`s and `DeepLinkMapper`s.````kotlin
class MyFeatureModuleInitializer : AppStartUp() {
override fun create(context: Context) {
with(GlobalRouterBuilder) {
add(MyActivityNameMapper)
add(MyFragmentNameMapper)
add(MyDeepLinkMapper)
}
}
}
````