Reputation: 10540
I've been using the android:autoLink
just fine for formatting links and such, but I need to use android:onClick
so I can't use that in this case. The reasoning is that I find it too easy to click on a phone number accidentally, so I'm going to intercept the click with a confirmation Dialog
and then call.
Is there an easy way to still make the phone number in my TextView
look like a normal clickable link? I poked around the Android source code, but couldn't find any particular style for me to reference.
Upvotes: 16
Views: 18128
Reputation: 1
Simply underline it:
val myText = "Text to be underlined"
textView.text = Html.fromHtml("<u>$myText</u>")
or with kotlin extensions:
fun TextView.underline() {
text = Html.fromHtml("<u>${text}</u>")
}
usage:
textView.text = myText
textView.underline()
More ways to style text in android here: https://medium.com/androiddevelopers/spantastic-text-styling-with-spans-17b0c16b4568
Upvotes: 0
Reputation: 3043
With kotlin extension function (if you don't need the click effect as on a real link)
fun TextView.hyperlinkStyle() {
setText(
SpannableString(text).apply {
setSpan(
URLSpan(""),
0,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
},
TextView.BufferType.SPANNABLE
)
}
How to use
yourTextView.hyperlinkStyle()
Upvotes: 1
Reputation: 1887
Have a better answer.This is what i did.
final SpannableString ss = new SpannableString("Click here to verify Benificiary");
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
};
ss.setSpan(clickableSpan,0,ss.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.BLUE);
You go anywhere you like when user clicks on the link through onclick method of ClickableSpan
Upvotes: 0
Reputation: 116332
This is the shortest solution:
final CharSequence text = tv.getText();
final SpannableString spannableString = new SpannableString( text );
spannableString.setSpan(new URLSpan(""), 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(spannableString, TextView.BufferType.SPANNABLE);
Sadly, the effect of clicking doesn't show up as being clicked on a real url link, but you can overcome it like so:
final CharSequence text = tv.getText();
final SpannableString notClickedString = new SpannableString(text);
notClickedString.setSpan(new URLSpan(""), 0, notClickedString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
final SpannableString clickedString = new SpannableString(notClickedString);
clickedString.setSpan(new BackgroundColorSpan(Color.GRAY), 0, notClickedString.length(),
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
tv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(final View v, final MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
tv.setText(clickedString);
break;
case MotionEvent.ACTION_UP:
tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
v.performClick();
break;
case MotionEvent.ACTION_CANCEL:
tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
break;
}
return true;
}
});
Another solution is to use Html.fromHtml(...) , where the text inside has links tags ("") .
If you wish for another solution, check this post.
Upvotes: 14
Reputation: 6690
To underline your TextView's text, you have to do something like:
final TextView text = (TextView) findViewById(R.id.text);
SpannableString string = new SpannableString("This is the uderlined text.");
string.setSpan(new UnderlineSpan(), 0, string.length(), 0);
text.setText(string);
This should work. Let me know about your progress.
Upvotes: 3
Reputation: 86948
Linkify is a great class, it hunts for complex patterns like URLs, phone numbers, etc and turns them into URLSpans. Rather than re-write the existing regular expressions I extended the URLSpan class and created a method to upgrade only the telephone URLSpans to a custom URLSpan with a confirmation dialog.
First my extended URLSpan class, ConfirmSpan:
class ConfirmSpan extends URLSpan {
AlertDialog dialog;
View mView;
public ConfirmSpan(URLSpan span) {
super(span.getURL());
}
@Override
public void onClick(View widget) {
mView = widget;
if(dialog == null) {
AlertDialog.Builder mBuilder = new AlertDialog.Builder(widget.getContext());
mBuilder.setMessage("Do you want to call: " + getURL().substring(4) + "?");
mBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
})
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
openURL();
}
});
dialog = mBuilder.create();
}
dialog.show();
}
public void openURL() {
super.onClick(mView);
}
}
Next the method to swap out the different span classes:
private void swapSpans(TextView textView) {
Spannable spannable = (Spannable) textView.getText();
URLSpan[] spans = textView.getUrls();
for(URLSpan span : spans) {
if(span.getURL().toString().startsWith("tel:")) {
spannable.setSpan(new ConfirmSpan(span), spannable.getSpanStart(span), spannable.getSpanEnd(span), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.removeSpan(span);
}
}
}
Finally all you need to do is create a TextView with the autoLink attribute:
android:autoLink="phone"
And remember to call the swapSpans()
method. Understand that I wrote this for fun, there may be other methods of doing this but I am unaware of them at the moment. Hope this helps!
Upvotes: 3
Reputation: 13807
android:clickable="true"
or setClickable(true)
to
your TextViews to make them clickable!Upvotes: 3