Android:检测TextView中Twitter链接并在自定义WebView打开
解决方案:让TextView中的Twitter链接在自定义WebView打开
嘿,这个需求我之前做过,刚好有几个成熟的方案可以帮到你,直接上干货:
方法一:自定义ClickableSpan替换默认链接处理
这个方法最直接,我们可以把TextView里默认的URLSpan替换成自己定义的ClickableSpan,这样点击时就能触发我们的跳转逻辑。
1. 定义自定义ClickableSpan
public class TweetLinkSpan extends ClickableSpan { private final Context mContext; private final String mTargetUrl; public TweetLinkSpan(Context context, String url) { mContext = context; mTargetUrl = url; } @Override public void onClick(View widget) { // 跳转到你的自定义WebView页面 Intent webViewIntent = new Intent(mContext, CustomWebViewActivity.class); webViewIntent.putExtra("WEB_URL", mTargetUrl); mContext.startActivity(webViewIntent); } @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); // 自定义链接样式,比如设置颜色和下划线 ds.setColor(ContextCompat.getColor(mContext, R.color.twitter_link_color)); ds.setUnderlineText(true); } }
2. 处理推文内容并替换Span
如果你的推文内容是HTML格式(Twitter API返回的内容通常是带HTML标签的),可以用Html.fromHtml配合自定义TagHandler来替换默认的链接Span:
public class TweetTagHandler implements Html.TagHandler { private final Context mContext; public TweetTagHandler(Context context) { mContext = context; } @Override public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { // 只处理<a>标签的结束标签 if (!opening && tag.equalsIgnoreCase("a")) { int lastPos = output.length(); // 获取默认的URLSpan URLSpan[] spans = output.getSpans(lastPos - 1, lastPos, URLSpan.class); if (spans.length > 0) { URLSpan oldSpan = spans[0]; // 移除默认Span,添加自定义Span output.removeSpan(oldSpan); output.setSpan( new TweetLinkSpan(mContext, oldSpan.getURL()), output.getSpanStart(oldSpan), output.getSpanEnd(oldSpan), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); } } } }
3. 绑定到TextView
TextView tweetTv = findViewById(R.id.tv_tweet_content); String tweetHtmlContent = "你的Twitter推文HTML内容(比如从API获取的)"; // 解析HTML并应用自定义TagHandler Spanned processedContent = Html.fromHtml( tweetHtmlContent, Html.FROM_HTML_MODE_COMPACT, null, new TweetTagHandler(this) ); tweetTv.setText(processedContent); tweetTv.setMovementMethod(LinkMovementMethod.getInstance()); tweetTv.setLinkTextColor(ContextCompat.getColor(this, R.color.twitter_link_color));
方法二:自定义LinkMovementMethod拦截点击
如果不想替换Span,也可以通过拦截TextView的触摸事件来捕获链接点击:
public class CustomLinkMovement extends LinkMovementMethod { private final Context mContext; public CustomLinkMovement(Context context) { mContext = context; } @Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP) { int x = (int) event.getX() - widget.getTotalPaddingLeft() + widget.getScrollX(); int y = (int) event.getY() - widget.getTotalPaddingTop() + widget.getScrollY(); Layout layout = widget.getLayout(); int line = layout.getLineForVertical(y); int offset = layout.getOffsetForHorizontal(line, x); // 获取点击位置的URLSpan URLSpan[] spans = buffer.getSpans(offset, offset, URLSpan.class); if (spans.length > 0) { String targetUrl = spans[0].getURL(); // 跳转到自定义WebView Intent intent = new Intent(mContext, CustomWebViewActivity.class); intent.putExtra("WEB_URL", targetUrl); mContext.startActivity(intent); return true; } } return super.onTouchEvent(widget, buffer, event); } }
然后给TextView设置这个MovementMethod:
tweetTv.setMovementMethod(new CustomLinkMovement(this));
自定义WebView页面示例
最后别忘了实现你的CustomWebViewActivity,确保链接在内部打开:
public class CustomWebViewActivity extends AppCompatActivity { private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); mWebView = findViewById(R.id.web_view); WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setDomStorageEnabled(true); // 获取传递的URL并加载 String targetUrl = getIntent().getStringExtra("WEB_URL"); if (targetUrl != null) { mWebView.loadUrl(targetUrl); } // 拦截WebView内的链接,继续在当前WebView打开 mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { view.loadUrl(request.getUrl().toString()); return true; } }); } }
注意事项
- 如果你的推文是纯文本格式(不带HTML标签),需要先用正则表达式匹配出所有链接,再手动给这些链接添加
TweetLinkSpan。 - 记得在
AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 如果使用Twitter官方SDK获取推文,返回的
full_text或text字段可能已经包含处理好的HTML链接,直接用上面的方法即可。
内容的提问来源于stack exchange,提问作者Ravi
相关产品推荐
相关产品推荐

