Clickable URLs in Android TextViews

http://blog.elsdoerfer.name/2009/10/29/clickable-urls-in-android-textviews/


Android’s TextView widget can contain clickable URLs. It can easily make web addresses open in the browser, or connect phone numbers with the dialer. All that is amazing compared to the last GUI framework I used, Delphi’s once great VCL).

Unfortunately, both TextView and the Linkify utility it uses basically hardcode URL click handling to Intents, by way of the URLSpans they create. What if we want the link to affect something within your own Activity, say, display a dialog, or enable a filter?

For example, in Autostarts, if the user’s filters cause the application list to be empty, I wanted to display an explanatory message, and provide a quick and easy way for the user to rectify the situation, i.e. lead him towards the filter selection dialog. Making the whole text clickable is hard to get right visually, and I didn’t like the idea of a button too much. A link within the text seemed perfect.

Now, we could just use a custom URL scheme of course, and register our Activity to handle Intents for that scheme, but that seemed much too heavy, if not hacky. Why shouldn’t we be able to just hook up an onClick handler?

As mentioned, URLSpan doesn’t allow us to change the way it handles clicks (it always sends off an Intent), but we can create a subclass:

  1. static class InternalURLSpan extends ClickableSpan {  
  2.     OnClickListener mListener;  
  3.   
  4.     public InternalURLSpan(OnClickListener listener) {  
  5.         mListener = listener;  
  6.     }  
  7.   
  8.     @Override  
  9.     public void onClick(View widget) {  
  10.         mListener.onClick(widget);  
  11.     }  
  12. }  

That looks pretty decent. Actually using that class it is tougher. There is no way to tell TextView or Linkify to use our custom span. In fact, Linkify actually has a method (applyLink) that would be nearly perfect to override, but declares it final.

So, we end up having to generate the spans manually; note nice, but hey, it works.

  1. SpannableString f = new SpannableString("....")  
  2. f.setSpan(new InternalURLSpan(new OnClickListener() {  
  3.         public void onClick(View v) {  
  4.             showDialog(DIALOG_VIEW_OPTIONS);  
  5.         }  
  6.     }), x, y, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  

We probably also want the user to jump to your link my moving the focus (e.g. using the trackball), which we can do by setting the proper movement method:

  1. MovementMethod m = emptyText.getMovementMethod();  
  2. if ((m == null) || !(m instanceof LinkMovementMethod)) {  
  3.     if (textView.getLinksClickable()) {  
  4.         textView.setMovementMethod(LinkMovementMethod.getInstance());  
  5.     }  
  6. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值