หาก Matcher ที่ให้มา ไม่เพียงพอต่อกรณีการใช้งานของคุณ คุณสามารถ
สร้าง Matcher ของคุณเองได้โดยการขยายคลาส DeepLinkMatcher
เมื่อขยาย DeepLinkMatcher<T, R> คุณต้องระบุอาร์กิวเมนต์ประเภท 2 รายการ ได้แก่ ประเภทคีย์การนำทางปลายทาง (T : Any) และประเภทผลการจับคู่ (R : DeepLinkMatcher.MatchResult<T>) หาก Matcher ไม่จำเป็นต้องมีการจัดอันดับผลลัพธ์ที่กำหนดเองหรือข้อมูลเมตาเพิ่มเติม ให้ใช้ DeepLinkMatcher.MatchResult<T> เป็นอาร์กิวเมนต์ประเภทที่ 2
ตัวอย่างเช่น นี่คือการใช้งานพื้นฐานของ TelDeepLinkMatcher ที่
รองรับ URI tel (เช่น tel:5550100) เนื่องจาก URI tel เป็นแบบทึบแสง
UriDeepLinkMatcher จึงไม่รองรับ URI ดังกล่าว
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 ที่กำหนดเอง
หากมีวิธีที่มีความหมายในการเปรียบเทียบผลการจับคู่จาก Matcher ที่กำหนดเอง
คุณควรขยาย DeepLinkMatcher.MatchResult และลบล้างเมธอด
compareTo เพื่อจัดอันดับผลลัพธ์
เมื่อสร้างคลาสย่อย MatchResult ที่กำหนดเอง ให้อัปเดตการประกาศคลาสของ Matcher
เพื่อระบุคลาสย่อยนั้นเป็นพารามิเตอร์ประเภทที่ 2 R (เช่น
class TelDeepLinkMatcher : DeepLinkMatcher<DialerKey, TelMatchResult>())
ซึ่งจะช่วยให้ผู้เรียกเข้าถึงพร็อพเพอร์ตี้ผลลัพธ์ที่กำหนดเองได้โดยไม่ต้องทำการดาวน์แคสต์ที่ไม่ได้ตรวจสอบ
ตัวอย่างเช่น หากต้องการรองรับการจับคู่รูปแบบไวลด์การ์ดใน TelDeepLinkMatcher คุณสามารถใช้ TelMatchResult เพื่อให้แน่ใจว่าการจับคู่ที่ตรงทั้งหมดจะได้รับการจัดอันดับสูงกว่าการจับคู่ไวลด์การ์ด หาก Matcher ห่ออยู่ใน 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 } }