Wenn die bereitgestellten Matcher für Ihre Anwendungsfälle nicht ausreichen, können Sie
eigene erstellen, indem Sie die Klasse DeepLinkMatcher erweitern.
Wenn Sie DeepLinkMatcher<T, R> erweitern, müssen Sie zwei Typargumente angeben: den
Typ des Navigationsschlüssels für das Ziel (T : Any) und den Typ des Match-Ergebnisses
(R : DeepLinkMatcher.MatchResult<T>). Wenn Ihr Matcher kein benutzerdefiniertes
Ranking der Ergebnisse oder keine zusätzlichen Metadaten benötigt, verwenden Sie DeepLinkMatcher.MatchResult<T> als
zweites Typargument.
Hier ist beispielsweise eine einfache Implementierung eines TelDeepLinkMatcher, der
tel URIs unterstützt (z. B. tel:5550100). Da tel URIs undurchsichtig sind,
UriDeepLinkMatcher sie nicht unterstützt:
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)) } }
MatchResult-Klassen benutzerdefiniert einstufen
Wenn es eine sinnvolle Möglichkeit gibt, Match-Ergebnisse aus Ihrem benutzerdefinierten Matcher zu vergleichen,
sollten Sie DeepLinkMatcher.MatchResult erweitern und die
compareTo Methode überschreiben, um die Ergebnisse einzustufen.
Wenn Sie eine benutzerdefinierte MatchResult Unterklasse erstellen, aktualisieren Sie die Klassendeklaration Ihres Matchers, um diese Unterklasse als zweiten Typparameter R anzugeben (z. B. class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, TelMatchResult>()). So können Aufrufer auf Ihre benutzerdefinierten Ergebniseigenschaften zugreifen, ohne eine nicht überprüfte Typumwandlung durchzuführen.
Wenn Sie beispielsweise die Platzhaltermustererkennung in TelDeepLinkMatcher unterstützen möchten, können Sie TelMatchResult implementieren, um sicherzustellen, dass genaue Übereinstimmungen höher eingestuft werden als Platzhalterübereinstimmungen. Wenn der Matcher in withBackStack eingeschlossen ist, heben Sie die Umschließung von
WrappedMatchResult auf, bevor Sie einen Vergleich durchführen, damit die Priorität anhand des zugrunde liegenden Match-Ergebnisses bewertet wird:
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 } }