Clickable URLs in Android TextViews
2012-06-09 14:35
351 查看
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:
view plaincopy to clipboardprint?
static class InternalURLSpan extends ClickableSpan {
OnClickListener mListener;
public InternalURLSpan(OnClickListener listener) {
mListener = listener;
}
@Override
public void onClick(View widget) {
mListener.onClick(widget);
}
}
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.
view plaincopy to clipboardprint?
SpannableString f = new SpannableString("....")
f.setSpan(new InternalURLSpan(new OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_VIEW_OPTIONS);
}
}), 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:
view plaincopy to clipboardprint?
MovementMethod m = emptyText.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (textView.getLinksClickable()) {
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
This
entry was posted by admin on 05:28, Oct 29th 2009 and filed in
Android.
You can subscribe the RSS Feed,
leave a reply or
trackback from your own blog.
----------------------------------------------------------------------------------
Why did you have to create a custom subclass of ClickableSpan. Instead you can create a ClickableSpan variable:
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:
view plaincopy to clipboardprint?
static class InternalURLSpan extends ClickableSpan {
OnClickListener mListener;
public InternalURLSpan(OnClickListener listener) {
mListener = listener;
}
@Override
public void onClick(View widget) {
mListener.onClick(widget);
}
}
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.
view plaincopy to clipboardprint?
SpannableString f = new SpannableString("....")
f.setSpan(new InternalURLSpan(new OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_VIEW_OPTIONS);
}
}), 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:
view plaincopy to clipboardprint?
MovementMethod m = emptyText.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (textView.getLinksClickable()) {
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
This
entry was posted by admin on 05:28, Oct 29th 2009 and filed in
Android.
You can subscribe the RSS Feed,
leave a reply or
trackback from your own blog.
----------------------------------------------------------------------------------
Why did you have to create a custom subclass of ClickableSpan. Instead you can create a ClickableSpan variable:
ClickableSpan clickable = new ClickableSpan() { @Override public void onClick(View widget) { Log.e("select text", "hi"); } }; SpannableString f = new SpannableString("....") ; f.setSpan(clickable, x, y, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
相关文章推荐
- Android事件系统(2)ClickableSpan In Clickable TextView
- Understanding User Interface in Android - Part 2: Views(译)
- Creating custom and compound Views in Android - Tutorial(翻译)
- no lable views point to this text field with an android:lablFor=”@+id/@+id
- Error 11 No resource identifier found for attribute 'textAlignment' in package 'android' 问题解决
- 【Android笔记】引用第三方自定义控件出错:Tip: Use View.isInEditMode() in your custom views to skip code when shown in Eclipse
- Android use custom html tag in TextView
- How to disable cursor positioning and text selection in an EditText? (Android)
- Customizing Background and Text color in Options Menu Android
- Android ApiDemos示例解析(196):Views->TextSwitcher
- Android学习—— TextView ClickableSpan 点击链接事件 改超链接颜色
- android错误:The method makeText(Context, CharSequence, int) in the type
- ArrayIndexOutOfBoundsException with custom Android Adapter for multiple views in ListView
- android错误:The method makeText(Context, CharSequence, int) in the type
- No resource identifier found for attribute 'textAlignment' in package 'android',
- android错误:The method makeText(Context, CharSequence, int) in the type
- [Android][Rendering Problems] Failed to find style 'editTextStyle' in current theme 解决方法
- No label views point to this text field with an android:labelFor="@+id/@+id/***" attribute
- Is there any way to define a min and max value for edittext in android?
- Customizing your button or TextView or another view in ANDROID.