Если предоставленных сопоставителей недостаточно для ваших целей, вы можете создать собственный, расширив класс DeepLinkMatcher.
При расширении DeepLinkMatcher<T, R> необходимо указать два аргумента типа: тип ключа навигации по пункту назначения (T : Any) и тип результата сопоставления (R : DeepLinkMatcher.MatchResult<T>). Если вашему сопоставителю не требуется настраиваемое ранжирование результатов или дополнительные метаданные, используйте DeepLinkMatcher.MatchResult<T> в качестве второго аргумента типа.
Например, ниже показана базовая реализация TelDeepLinkMatcher, которая поддерживает URI tel (такие как tel:5550100). Поскольку URI tel непрозрачны, UriDeepLinkMatcher их не поддерживает:
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 класса
Если есть способ сравнить результаты сопоставления, полученные с помощью вашего средства сопоставления, расширьте класс DeepLinkMatcher.MatchResult и переопределите метод compareTo, чтобы ранжировать результаты.
При создании пользовательского подкласса MatchResult обновите объявление класса сопоставителя, чтобы указать этот подкласс в качестве второго параметра типа R (например, class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, TelMatchResult>()). Это позволит вызывающим объектам получать доступ к свойствам пользовательского результата без непроверенного нисходящего приведения типов.
Например, чтобы поддерживать сопоставление с подстановочными знаками в TelDeepLinkMatcher, можно реализовать TelMatchResult, чтобы точные соответствия ранжировались выше, чем совпадения с подстановочными знаками. Если сопоставитель заключен в withBackStack, то перед сравнением удалите WrappedMatchResult, чтобы приоритет оценивался по результату сопоставления.
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 } }