Jika pencocok yang disediakan tidak cukup untuk kasus penggunaan Anda, Anda dapat
membuat pencocok sendiri dengan memperluas class DeepLinkMatcher.
Saat memperluas DeepLinkMatcher<T, R>, Anda harus menentukan dua argumen jenis: jenis kunci navigasi tujuan (T : Any) dan jenis hasil pencocokan (R : DeepLinkMatcher.MatchResult<T>). Jika pencocok Anda tidak memerlukan peringkat hasil kustom atau metadata tambahan, gunakan DeepLinkMatcher.MatchResult<T> sebagai argumen jenis kedua.
Misalnya, berikut adalah implementasi dasar TelDeepLinkMatcher yang
mendukung URI tel (seperti tel:5550100). Karena URI tel bersifat buram,
UriDeepLinkMatcher tidak mendukungnya:
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)) } }
Memberi peringkat pada MatchResult class kustom
Jika ada cara yang bermakna untuk membandingkan hasil pencocokan dari pencocok kustom,
Anda harus memperluas DeepLinkMatcher.MatchResult dan mengganti
metode compareTo untuk memberi peringkat hasil.
Saat Anda membuat subclass MatchResult kustom, perbarui deklarasi class matcher Anda
untuk menentukan subclass tersebut sebagai parameter jenis kedua R (seperti
class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, TelMatchResult>()).
Hal ini memungkinkan pemanggil mengakses properti hasil kustom Anda tanpa downcasting
yang tidak dicentang.
Misalnya, untuk mendukung pencocokan pola karakter pengganti di TelDeepLinkMatcher, Anda
dapat menerapkan TelMatchResult untuk memastikan pencocokan persis memiliki peringkat lebih tinggi daripada
pencocokan karakter pengganti. Jika matcher digabungkan dalam withBackStack, buka gabungan
WrappedMatchResult sebelum membandingkan agar prioritas dievaluasi
terhadap hasil pencocokan yang mendasarinya:
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 } }