Se i matcher forniti non sono sufficienti per i tuoi casi d'uso, puoi crearne uno tuo 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 della corrispondenza (R : DeepLinkMatcher.MatchResult<T>). Se il tuo matcher non richiede un ranking dei risultati personalizzato o metadati aggiuntivi, utilizza DeepLinkMatcher.MatchResult<T> come secondo argomento di tipo.
Ad esempio, ecco un'implementazione di base di un TelDeepLinkMatcher che supporta gli URI tel (come 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)) } }
Classifica le classi MatchResult personalizzate
Se esiste un modo significativo per confrontare i risultati di corrispondenza del tuo matcher personalizzato,
devi estendere DeepLinkMatcher.MatchResult ed eseguire l'override del
metodo compareTo 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 downcast non controllato.
Ad esempio, per supportare la corrispondenza di pattern con caratteri jolly in TelDeepLinkMatcher, puoi implementare un TelMatchResult per assicurarti che le corrispondenze esatte abbiano un ranking più elevato rispetto alle corrispondenze con caratteri jolly. Se l'elemento di corrispondenza è racchiuso tra withBackStack, rimuovi
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 } }