【问题标题】:Make a string clickable, underlined in a TextView使字符串可点击,在 TextView 中加下划线
【发布时间】:2015-06-07 03:31:51
【问题描述】:

我想让字符串“this link”带下划线和可点击,但我不知道如何实现。

XML 文件:

<string name="submitText">Before you submit, please check out &lt;u>this link&lt;/u></string>

在我的片段中:

tvSubmit.setText(Html.fromHtml(getString(R.string.submitText)));

我不希望整个字符串都是可点击的,只有带下划线的部分。我不能使用带有 2 个单元格的水平 LinearLayout,因为在较小的设备上,字符串不会有连续的外观,它将被分成 2 个单元格。

我尝试了什么:

tvSubmit.setMovementMethod(LinkMovementMethod.getInstance());
Spannable sp = (Spannable) tvSubmit.getText();
ClickableSpan click = new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        showLink();
    }
};
sp.setSpan(click, 0, sp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

上面的代码使整个字符串加了下划线,并且文本的颜色变成了浅蓝色。

【问题讨论】:

  • 你可以使用HTML.fromHTML并在你的字符串中插入一个&lt;a href="..."&gt;this link&lt;/a&gt;

标签: android hyperlink textview underline


【解决方案1】:

问题在于您将跨度设置为整个字符串 (sp.setSpan(click, 0, sp.length())。要解决此问题,您必须仅在 this link 上设置可点击范围。我也是这样做的:

<string name="submitText">Before you submit, please check out %1$s</string>
<string name="this_link">this link</string>

在您的活动中

String thisLink = getString(R.string.thisLink);
String yourString = getString(R.string.submitText, thisLink);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(yourString);
spannableStringBuilder.setSpan(click,
                startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

其中 startIndex 和 endIndex 是thisLinkyourString 中的索引。我将这两个字符串分开是因为查找索引更容易,尤其是在您必须处理翻译的情况下。要计算 startIndex,您可以使用 yourString.indexOf(thisLink),endIndex 是 startIndex + the length of thisLink。我将把普通检查留给你,(负索引,以及可能导致IndexOutBoundException 的所有其他内容)

【讨论】:

    【解决方案2】:

    你可以在你的 strings.xml 中定义

    <string name="submitText">Before you submit, please check out <a href="actual url">this link</a>
    

    【讨论】:

      【解决方案3】:
       <TextView  
             android:id="@+id/tvSubmit"  
             android:layout_width="wrap_content"  
             android:layout_height="wrap_content"  
             android:layout_alignParentTop="true"  
             android:autoLink=@String/submitText //link the content of web  
             android:textColorLink="#576586" //change the color of the link  
             android:textColor="#555555" />
      

      在活动中 //样本

      String webLinkText = <a href="https://prativas.files.wordpress.com/2013/05/screenshot-mozilla-firefox-private-browsing.png"><img src="https://prativas.files.wordpress.com/2013/05/screenshot-mozilla-firefox-private-browsing.png" alt="Screenshot-Mozilla Firefox (Private Browsing)" width="293" height="254" class="alignnone size-full wp-image-291" /></a>  
       tvSubmit = (TextView) findViewById(R.id.tvSubmit);  
       tvSubmit.setText(Html.fromHtml(webLinkText))); 
      

      在这里查看for more detailed answer

      【讨论】:

        【解决方案4】:

        您可以尝试使用 Kotlin 扩展功能来创建类似文本并且还可以通过下划线单击。

        fun TextView.colorSpannableStringWithUnderLineOne(
            prefixString: String,
            postfixString: String,
            callback: (Int) -> Unit
        ) {
            val spanTxt = SpannableStringBuilder()
            spanTxt.append("$prefixString ")
            spanTxt.append(" $postfixString")
            spanTxt.setSpan(object : ClickableSpan() {
                override fun onClick(widget: View) {
                    callback(0)
                    widget.invalidate()
                }
        
                override fun updateDrawState(ds: TextPaint) {
                    ds.color = ContextCompat.getColor(context, R.color.highlight)
                    ds.isUnderlineText = true
                }
            }, prefixString.length, spanTxt.length, 0)
            this.movementMethod = LinkMovementMethod.getInstance()
            this.setText(spanTxt, TextView.BufferType.SPANNABLE)
        }
        

        `

        如何使用:

        textViewLink.colorSpannableStringWithUnderLineOne(
                        "Normal string",
                        "Clickable string",
                        callback = {
                            JLog.e("==>","Clicked")
                        })
          textViewLink.invalidate()
        

        【讨论】:

          【解决方案5】:

          在我的情况下,我需要一个本地化的字符串,其中一部分是可点击的。 我所做的是在我的资源中定义一个字符串(每个语言环境一个),可点击部分加下划线,如下所示:

          <string name="my_message">Blah blah blah <u>call us</u> blah blah.</string>
          

          然后我创建了一个扩展来查找带下划线的文本并在其上添加可点击的跨度,如下所示:

          fun CharSequence.makeUnderlineClickable(listener: (index: Int) -> Unit): SpannableString {
              val spannedString = SpannableString(this)
              spannedString.getSpans(0, length, UnderlineSpan::class.java)?.forEachIndexed { index, underlineSpan ->
                  val clickableSpan = object : ClickableSpan() {
                      override fun onClick(widget: View) {
                          listener.invoke(index)
                      }
          
                      override fun updateDrawState(ds: TextPaint) {
                          ds.isUnderlineText = true
                      }
                  }
                  spannedString.setSpan(
                      clickableSpan,
                      spannedString.getSpanStart(underlineSpan),
                      spannedString.getSpanEnd(underlineSpan),
                      Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                  )
              }
              return spannedString 
          }
          

          你可以这样使用它:

              textView.text = resources.getText(R.string.my_message).makeUnderlineClickable { index ->
                  //handle click here
              }
              textView.movementMethod = LinkMovementMethod.getInstance()
              textView.highlightColor = Color.TRANSPARENT
          

          【讨论】:

          • 谢谢!另外为了让 textView 的其余部分选中复选框,我添加了以下 textView.setOnClickListener { if (selectionStart == -1 && selectionEnd == -1) { onCheckboxClick() } }
          【解决方案6】:
          sp.setSpan(click, 0, sp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          

          更改值 0 :在文本中以位置开始链接,示例更改值:10 如果设置为 0,它将超链接所有文本。

          【讨论】:

            【解决方案7】:

            刚刚制作了这个函数来帮助我将可点击的文本附加到 textview :

            public static SpannableStringBuilder getSpannablableClickFor(CharSequence initialText, ClickableSpan click, String textToAppend) {
                String description = String.format("%s %s", initialText, textToAppend);
                SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(description);
                int start = description.indexOf(textToAppend);
                int end = start + textToAppend.length();
                spannableStringBuilder.setSpan(click,
                        start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                spannableStringBuilder.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                spannableStringBuilder.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.WHITE);
                spannableStringBuilder.setSpan(fcs, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                return spannableStringBuilder;
            }
            

            【讨论】:

              【解决方案8】:

              你可以试试下面的代码..

              String str = "Before you submit, please check out this link";
              tvSubmit.setMovementMethod(LinkMovementMethod.getInstance());
              tvSubmit.setText(setClickablePart(str), BufferType.SPANNABLE);
              

              使用以下方法处理Textview中的点击事件

               private SpannableStringBuilder setClickablePart(String str)
                  {
                      SpannableStringBuilder m_spannableStringBuilder = new SpannableStringBuilder(str);
              
                      int m_index = str.indexOf("this");
              
                      final String clickString = str.substring(m_index, str.length());
                      m_spannableStringBuilder.setSpan(new ClickableSpan()
                      {
                          @Override
                          public void onClick(View widget)
                          {
                              Toast.makeText(MainActivity.this, clickString, Toast.LENGTH_SHORT).show();
                          }
                      }, m_index, str.length(), 0);
              
                      return m_spannableStringBuilder;
                  }
              

              【讨论】:

              • 这不起作用,因为原始字符串实际上并不包含url...仔细阅读问题。
              • 请检查修改后的答案。
              猜你喜欢
              • 2013-04-07
              • 2018-03-16
              • 1970-01-01
              • 2020-02-13
              • 1970-01-01
              • 2011-11-17
              • 1970-01-01
              • 2012-01-23
              • 1970-01-01
              相关资源
              最近更新 更多