Se i matcher forniti non sono sufficienti per i tuoi casi d'uso, puoi
crearne di tuoi estendendo la classe DeepLinkMatcher.
Quando estendi DeepLinkMatcher<T, R>, devi specificare due argomenti di tipo: il
tipo di chiave di navigazione di destinazione (T : Any) e il tipo di risultato di corrispondenza
(R : DeepLinkMatcher.MatchResult<T>). Se il matcher non richiede un ranking dei risultati personalizzato o metadati aggiuntivi, utilizza DeepLinkMatcher.MatchResult<T> come il
secondo argomento di tipo.
Ad esempio, ecco un'implementazione di base di un TelDeepLinkMatcher che
supporta gli URI tel (ad esempio tel:5550100). Poiché gli URI tel sono opachi,
UriDeepLinkMatcher non li supporta:
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)) } }
Classificare le classi MatchResult personalizzate
Se esiste un modo significativo per confrontare i risultati di corrispondenza del matcher personalizzato,
devi estendere DeepLinkMatcher.MatchResult e sostituire il
compareTo metodo per classificare i risultati.
Quando crei una sottoclasse MatchResult personalizzata, aggiorna la dichiarazione della classe del matcher per specificare la sottoclasse come secondo parametro di tipo R (ad esempio class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, TelMatchResult>()). In questo modo, i chiamanti possono accedere alle proprietà dei risultati personalizzati senza eseguire il downcasting non controllato.
Ad esempio, per supportare la corrispondenza di pattern con caratteri jolly in TelDeepLinkMatcher, puoi implementare un TelMatchResult per garantire che le corrispondenze esatte abbiano un ranking più alto rispetto alle corrispondenze con caratteri jolly. Se il matcher è racchiuso in withBackStack, annulla il wrapping
WrappedMatchResult prima del confronto in modo che la precedenza venga valutata
rispetto al risultato di corrispondenza sottostante:
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 } }