Si les matchers fournis ne suffisent pas pour vos cas d'utilisation, vous pouvez créer les vôtres en étendant la classe DeepLinkMatcher.
Lorsque vous étendez DeepLinkMatcher<T, R>, vous devez spécifier deux arguments de type : le type de clé de navigation de destination (T : Any) et le type de résultat de correspondance (R : DeepLinkMatcher.MatchResult<T>). Si votre outil de mise en correspondance n'a pas besoin d'un classement personnalisé des résultats ni de métadonnées supplémentaires, utilisez DeepLinkMatcher.MatchResult<T> comme deuxième argument de type.
Par exemple, voici une implémentation de base d'un TelDeepLinkMatcher compatible avec les URI tel (comme tel:5550100). Comme les URI tel sont opaques, UriDeepLinkMatcher n'est pas compatible avec eux :
class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, DeepLinkMatcher.MatchResult<DialerKey>>() { override fun matchRequest(request: DeepLinkRequest): MatchResult<DialerKey>? { val uri = request.uri ?: return null if (uri.scheme != "tel") return null // Note: schemeSpecificPart is only available on Android val phoneNumber = uri.schemeSpecificPart ?: return null return MatchResult(DialerKey(phoneNumber = phoneNumber)) } }
Classer les classes MatchResult personnalisées
S'il existe un moyen pertinent de comparer les résultats de correspondance de votre outil de mise en correspondance personnalisé, vous devez étendre DeepLinkMatcher.MatchResult et remplacer la méthode compareTo pour classer les résultats.
Lorsque vous créez une sous-classe MatchResult personnalisée, mettez à jour la déclaration de classe de votre outil de mise en correspondance pour spécifier cette sous-classe comme deuxième paramètre de type R (par exemple, class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, TelMatchResult>()). Cela permet aux appelants d'accéder aux propriétés de vos résultats personnalisés sans conversion descendante non vérifiée.
Par exemple, pour prendre en charge la correspondance de modèles avec des caractères génériques dans TelDeepLinkMatcher, vous pouvez implémenter un TelMatchResult pour vous assurer que les correspondances exactes sont mieux classées que les correspondances avec des caractères génériques. Si l'outil de mise en correspondance est encapsulé dans withBackStack, désencapsulez WrappedMatchResult avant de comparer afin que la priorité soit évaluée par rapport au résultat de correspondance sous-jacent :
class TelMatchResult( key: DialerKey, val isExactMatch: Boolean, val patternLength: Int ) : DeepLinkMatcher.MatchResult<DialerKey>(key) { override fun compareTo(other: DeepLinkMatcher.MatchResult<DialerKey>): Int { // Unwrap if the other result is wrapped in a BackStackMatchResult or custom WrappedMatchResult val target = if (other is WrappedMatchResult<*>) other.matchResult else other if (target !is TelMatchResult) { // Determine precedence relative to other MatchResult types (e.g. UriMatchResult) return 1 } // An exact match wins over a wildcard/prefix match if (isExactMatch && !target.isExactMatch) return 1 if (!isExactMatch && target.isExactMatch) return -1 // The more specific (longer) pattern wins (e.g., tel:1800* versus tel:*) val lengthDiff = this.patternLength - target.patternLength if (lengthDiff != 0) { return lengthDiff } return 0 } }