Jeśli podane dopasowania nie są wystarczające w Twoich przypadkach użycia, możesz
utworzyć własne, rozszerzając klasę DeepLinkMatcher.
Rozszerzając DeepLinkMatcher<T, R>, musisz określić 2 argumenty typu: typ klucza nawigacji do miejsca docelowego (T : Any) i typ wyniku dopasowania (R : DeepLinkMatcher.MatchResult<T>). Jeśli dopasowanie nie wymaga niestandardowego rankingu wyników ani dodatkowych metadanych, użyj DeepLinkMatcher.MatchResult<T> jako drugiego argumentu typu.
Oto na przykład podstawowa implementacja TelDeepLinkMatcher, która
obsługuje identyfikatory URI tel (np. tel:5550100). Ponieważ identyfikatory URI tel są nieprzezroczyste,
UriDeepLinkMatcher ich nie obsługuje:
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)) } }
Ranking niestandardowych klas MatchResult
Jeśli istnieje sensowny sposób porównywania wyników dopasowania z niestandardowego dopasowania,
rozszerz DeepLinkMatcher.MatchResult i zastąp metodę
compareTo, aby określić ranking wyników.
Gdy utworzysz niestandardową podklasę MatchResult, zaktualizuj deklarację klasy dopasowania
, aby określić tę podklasę jako drugi parametr typu R (np.
class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, TelMatchResult>()).
Dzięki temu osoby wywołujące mogą uzyskiwać dostęp do niestandardowych właściwości wyniku bez sprawdzania
rzutowania w dół.
Aby na przykład obsługiwać dopasowywanie wzorców z symbolami wieloznacznymi w TelDeepLinkMatcher, możesz zaimplementować TelMatchResult, aby zapewnić, że dokładne dopasowania będą miały wyższy ranking niż dopasowania z symbolami wieloznacznymi. Jeśli dopasowanie jest opakowane w withBackStack, rozpakuj
WrappedMatchResult przed porównaniem, aby pierwszeństwo było oceniane
na podstawie bazowego wyniku dopasowania:
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 } }