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.
Just like Buttons and ImageViews we can add onClickListeners to TextViews by simply adding the attribute android:onClick="myMethod" to your TextView XML tag. The other way, TextView tv = (TextView) this.
To call linkify in android, we have to call linkify. addLinks(), in that method we have to pass textview and LinkifyMask. Linkify. WEB_URLS: It going make URL as web url, when user click on it, it going to send url to default web browsers.
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.
android:clickable="true"
or setClickable(true)
to
your TextViews to make them clickable!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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With