使用 Linkify.addLinks() 時,若需「匹配某模式(如域名),但點擊跳轉到不同 URL(如註冊頁)」,需使用 TransformFilter 修改實際跳轉 URL。
// 期望:匹配 "https://www.abc.com" 但跳轉到 "https://www.abc.com?m=signup"
Linkify.addLinks(tv, Pattern.compile("https://www.abc.com"), "https://www.abc.com?m=signup");
// 實際:點擊仍跳轉到 "https://www.abc.com"
Linkify 的第三個參數 scheme 是為無協議頭的匹配文本添加協議(如匹配 "www.abc.com" 添加 "https://" 變為完整 URL)。若匹配文本已包含完整 URL,則直接使用匹配文本作為跳轉目標,忽略 scheme 參數。
TransformFilter transformFilter = new TransformFilter() {
@Override
public String transformUrl(Matcher match, String url) {
// 返回實際想要跳轉的 URL
return "https://www.abc.com/?m=signup";
}
};
Linkify.addLinks(
tv,
Pattern.compile("https://www.abc.com"), // 匹配模式
"https://www.abc.com/?m=signup", // scheme(此處實際不生效,但必填)
null, // MatchFilter(可選)
transformFilter // 關鍵:修改最終 URL
);
public static void addLinks(TextView text,
Pattern pattern, // 匹配正則
String scheme, // 為無協議文本添加的協議
MatchFilter matchFilter, // 額外匹配過濾
TransformFilter transformFilter) // URL 轉換器
Pattern pattern = Pattern.compile("@(\\w+)"); // 匹配 @用戶名
TransformFilter filter = new TransformFilter() {
@Override
public String transformUrl(Matcher match, String url) {
// match.group(1) 獲取用戶名
String username = match.group(1);
return "myapp://profile/" + username; // 自定義 Scheme
}
};
Linkify.addLinks(textView, pattern, "myapp://profile/", null, filter);
transformUrl 返回的 URL 會直接用於 Intent.ACTION_VIEWAndroidManifest.xml 配置對應 intent-filter複雜交互建議使用 SpannableString + ClickableSpan 完全控制:
SpannableString spannable = new SpannableString("查看完整版");
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
// 完全自定義跳轉邏輯
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.abc.com?m=signup")));
}
}, 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannable);
textView.setMovementMethod(LinkMovementMethod.getInstance());