Format TextView to look like link

前端 未结 7 1559
醉话见心
醉话见心 2021-01-04 02:21

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.

相关标签:
7条回答
  • 2021-01-04 02:46

    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!

    0 讨论(0)
  • 2021-01-04 02:48
    • 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!
    0 讨论(0)
  • 2021-01-04 02:54

    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.

    0 讨论(0)
  • 2021-01-04 02:54

    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()
    
    0 讨论(0)
  • 2021-01-04 02:56

    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.

    0 讨论(0)
  • 2021-01-04 02:59

    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

    0 讨论(0)
提交回复
热议问题