【问题标题】:AutoLink with hyperLink android自动链接与超链接 android
【发布时间】:2016-04-03 10:05:13
【问题描述】:

我有一个文本视图,其中可以包含https://www.google.com 之类的链接和带有锚标记Google 的超链接

现在,我在这个 textview 上添加了以下属性。

Linkify.addLinks(textview, Linkify.WEB_URLS);
textview.setMovementMethod(LinkMovementMethod.getInstance());

但是像https://www.google.com 这样的链接可以正常显示为蓝色并重定向到页面,但锚标签没有显示为蓝色并且它们没有重定向它。

所以,我想让我的 textview 呈现两种类型的链接:直接链接和超链接。我该怎么做。

【问题讨论】:

    标签: android textview autolink


    【解决方案1】:

    Linkify(您调用它的方式)只知道转换实际上看起来像 Web URL 的内容(即它们以 http 或 https 开头,后跟冒号和两个斜杠等)。

    如果您想将其他内容转换为链接,则必须向Linkify 添加更多参数,以使其更智能地转换您想要的内容。你可以创建一个 MatchFilter 和一个 TransformFilter 然后调用Linkify.addLinks(TextView text, Pattern p, String scheme, Linkify.MatchFilter matchFilter, Linkify.TransformFilter transformFilter)

    但在我看来,您想使用“Google”之类的词并为“https://www.google.com”添加链接。那不是可以扫描的东西。为此,您需要使用SpannableStringBuilder。您的代码可能如下所示:

        String text = "This is a line with Google in it.";
        Spannable spannable = new SpannableString(text);
        int start = text.indexOf("Google");
        int end = start + "Google".length();
        URLSpan urlSpan = new URLSpan("https://www.google.com");
        spannable.setSpan(urlSpan, start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        textView.setText(spannable);
    

    【讨论】:

      【解决方案2】:

      Linkify#addLinks(Spannable, Int)javadoc 中提到:

      ...如果掩码不为零,它还会删除任何附加到 Spannable 的现有 URLSpans,以避免在同一文本上重复调用它时出现问题。

      虽然在您使用的Linkify#addLinks(TextView, Int) 中没有提到它,但似乎它们遵循相同的行为并且现有链接(即您问题中的“锚标记”)将在链接之前被删除。

      要解决并保留现有链接(在您的情况下为“锚标记”),您需要备份现有跨度(即 TextView#getText --> 转换为跨度 --> 使用 Spanned#getSpans 列出现有链接 -->使用Spanned#getSpanStartSpanned#getSpanEndSpanned#getSpanFlags 检索每个的设置)

      链接后,重新添加跨度(即TextView#getText --> 转换为Spannable --> 使用Spannable#setSpan 重新添加链接 --> 将Spannable 设置回TextView#setText )

      根据您的情况,您可能还需要检查重叠的“锚标签”和“链接链接”并进行相应调整...

      如您所见,这是相当乏味、复杂且容易出错的代码。为了简化事情,我只是将所有这些合并到Textoo 库中以供重用和共享。使用 Textoo,您可以通过以下方式实现相同目的:

      TextView myTextView = Textoo
                  .config((TextView) findViewById(R.id.view_location_disabled))
                  .linkifyWebUrls()
                  .apply();
      

      Textoo 将保留现有链接并链接所有不重叠的网址。

      【讨论】:

        【解决方案3】:
        //the string to add links to
        val htmlString = "This has anchors and urls http://google.com also <a href=\"http://google.com\">Google</a>."
        
        //Initial span from HtmlCompat will link anchor tags
        val htmlSpan = HtmlCompat.fromHtml(htmlString, HtmlCompat.FROM_HTML_MODE_LEGACY) as Spannable
        
        //save anchor links for later
        val anchorTagSpans = htmlSpan.getSpans(0, htmlSpan.length, URLSpan::class.java)
        
        //add first span to TextView
        textView.text = htmlSpan
        
        //Linkify will now make urls clickable but overwrite our anchor links
        Linkify.addLinks(textView, Linkify.ALL)
        textView.movementMethod = LinkMovementMethod.getInstance()
        textView.linksClickable = true
        
        //we will add back the anchor links here
        val restoreAnchorsSpan = SpannableString(textView.text)
        for (span in anchorTagSpans) {
            restoreAnchorsSpan.setSpan(span, htmlSpan.getSpanStart(span), htmlSpan.getSpanEnd(span), Spanned.SPAN_INCLUSIVE_INCLUSIVE)
        }
        
        //all done, set it to the textView
        textView.text = restoreAnchorsSpan
        

        【讨论】:

          猜你喜欢
          • 2016-12-13
          • 1970-01-01
          • 2016-05-24
          • 2017-02-21
          • 1970-01-01
          • 1970-01-01
          • 2012-07-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多