telkins
telkins

Reputation: 10540

Format TextView to look like link

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

Answers (7)

manu
manu

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

HendraWD
HendraWD

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

Debasish Ghosh
Debasish Ghosh

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

android developer
android developer

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

yugidroid
yugidroid

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

Sam
Sam

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

Bal&#225;zs &#201;des
Bal&#225;zs &#201;des

Reputation: 13807

  • You can create a colors.xml resource file, what contains colors. Please take a look at Colors
  • If you want to underline your text, then please take a look at this post: Underline
  • Don't forget to add android:clickable="true" or setClickable(true) to your TextViews to make them clickable!

Upvotes: 3

Related Questions