【问题标题】:Format TextView to look like link将 TextView 格式化为看起来像链接
【发布时间】:2012-08-02 23:11:30
【问题描述】:

我一直在使用android:autoLink 来格式化链接等,但我需要使用android:onClick,所以在这种情况下我不能使用它。原因是我发现误点击电话号码太容易了,所以我准备拦截点击确认Dialog然后拨打电话。

有没有一种简单的方法可以让我的TextView 中的电话号码看起来像一个普通的可点击链接?我翻遍了 Android 源代码,但找不到任何特定的样式供我参考。

【问题讨论】:

标签: android


【解决方案1】:

这是最短的解决方案:

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);

遗憾的是,点击的效果不会显示为点击真实的 url 链接,但您可以像这样克服它:

    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;
        }
    });

另一个解决方案是使用 Html.fromHtml(...) ,其中的文本有链接标签 ("") 。

如果您希望获得其他解决方案,请查看this post

【讨论】:

    【解决方案2】:
    • 您可以创建一个 colors.xml 资源文件,其中包含颜色。请看Colors
    • 如果你想给你的文字加下划线,那么请看看这个帖子: Underline
    • 别忘了将android:clickable="true"setClickable(true) 添加到 你的 TextView 让它们可点击!

    【讨论】:

      【解决方案3】:

      Linkify 是一个很棒的类,它寻找复杂的模式,如 URL、电话号码等,并将它们转换为 URLSpans。我没有重写现有的正则表达式,而是扩展了 URLSpan 类并创建了一个方法,将only电话 URLSpan 升级为带有确认对话框的自定义 URLSpan。

      首先我的扩展 URLSpan 类 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);
          }
      }
      

      接下来换出不同跨度类的方法:

      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);
              }
          }
      }
      

      最后你需要做的就是创建一个带有 autoLink 属性的 TextView:

      android:autoLink="phone"
      

      记得调用swapSpans() 方法。明白我写这个是为了好玩,可能还有其他方法可以做到这一点,但我目前不知道它们。希望这会有所帮助!

      【讨论】:

      • 谢谢,这看起来很不错!我将尝试尽快实施它,看看它是如何进行的。 :)
      【解决方案4】:

      要为 TextView 的文本添加下划线,您必须执行以下操作:

      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);
      

      这应该可行。让我知道你的进展。

      【讨论】:

      • 只需用字符串替换内容,然后只有您的代码可以正常工作。因为这里没有内容。
      【解决方案5】:

      带有kotlin扩展功能(如果你不需要真实链接的点击效果)

      fun TextView.hyperlinkStyle() {
          setText(
              SpannableString(text).apply {
                  setSpan(
                      URLSpan(""),
                      0,
                      length,
                      Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                  )
              },
              TextView.BufferType.SPANNABLE
          )
      }
      

      如何使用

      yourTextView.hyperlinkStyle()
      

      【讨论】:

        【解决方案6】:

        有一个更好的答案。这就是我所做的。

             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);
        

        当用户通过 ClickableSpan 的 onclick 方法点击链接时,你可以去任何你喜欢的地方

        【讨论】:

          【解决方案7】:

          简单地划线:

          val myText = "Text to be underlined"
          textView.text = Html.fromHtml("<u>$myText</u>")
          

          或使用 kotlin 扩展:

          fun TextView.underline() {
              text = Html.fromHtml("<u>${text}</u>")
          }
          

          用法:

          textView.text = myText
          textView.underline()
          

          更多在 android 中设置文本样式的方法:https://medium.com/androiddevelopers/spantastic-text-styling-with-spans-17b0c16b4568

          【讨论】:

            猜你喜欢
            • 2021-04-13
            • 2013-01-03
            • 1970-01-01
            • 2011-07-10
            • 2012-02-19
            • 1970-01-01
            • 2018-08-21
            • 2021-08-24
            • 2021-02-08
            相关资源
            最近更新 更多