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 Zielnavigationsschlüssels (T : Any) und den Typ des Übereinstimmungsergebnisses (R : DeepLinkMatcher.MatchResult<T>). Wenn Ihr Matcher kein benutzerdefiniertes Ergebnisranking oder zusätzliche Metadaten benötigt, verwenden Sie DeepLinkMatcher.MatchResult<T> als zweites Typargument.
Hier ist ein Beispiel für eine einfache Implementierung eines TelDeepLinkMatcher, der tel-URIs (z. B. tel:5550100) unterstützt. Da tel-URIs intransparent sind, werden sie von UriDeepLinkMatcher 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)) } }
Benutzerdefinierte MatchResult-Klassen bewerten
Wenn es eine sinnvolle Möglichkeit gibt, die Übereinstimmungsergebnisse Ihres benutzerdefinierten Matchers zu vergleichen, sollten Sie DeepLinkMatcher.MatchResult erweitern und die Methode compareTo überschreiben, um die Ergebnisse zu bewerten.
Wenn Sie eine benutzerdefinierte MatchResult-Unterklasse erstellen, aktualisieren Sie die Klassendeklaration Ihres Matchers, um diese Unterklasse als zweiten Typparameter R (z. B. class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, TelMatchResult>()) anzugeben. Dadurch können Aufrufer auf Ihre benutzerdefinierten Ergebniseigenschaften zugreifen, ohne dass ein ungeprüftes Downcasting erforderlich ist.
Wenn Sie beispielsweise den Platzhalter-Musterabgleich in TelDeepLinkMatcher unterstützen möchten, können Sie einen TelMatchResult implementieren, damit genaue Übereinstimmungen höher eingestuft werden als Platzhalter-Übereinstimmungen. Wenn der Matcher in withBackStack eingeschlossen ist, entfernen Sie WrappedMatchResult vor dem Vergleich, damit die Priorität anhand des zugrunde liegenden Übereinstimmungsergebnisses ausgewertet 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 } }