从TextView - Android中的链接中删除下划线

Moh*_*aou 82 android hyperlink underline textview

我使用两个textview来显示数据库的链接,我设法更改链接颜色,但我想删除下划线

email.setText(c.getString(5));
    website.setText(c.getString(6));
    Linkify.addLinks(email, Linkify.ALL);
    Linkify.addLinks(website, Linkify.ALL);
Run Code Online (Sandbox Code Playgroud)

我可以从XML或代码那样做吗?

Reu*_*ton 207

您可以通过URLSpan使用未加下划线的版本查找和替换实例来在代码中执行此操作.拨打电话后Linkify.addLinks(),请拨打stripUnderlines()下面粘贴的功能TextView:

    private void stripUnderlines(TextView textView) {
        Spannable s = new SpannableString(textView.getText());
        URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
        for (URLSpan span: spans) {
            int start = s.getSpanStart(span);
            int end = s.getSpanEnd(span);
            s.removeSpan(span);
            span = new URLSpanNoUnderline(span.getURL());
            s.setSpan(span, start, end, 0);
        }
        textView.setText(s);
    }
Run Code Online (Sandbox Code Playgroud)

这需要一个自定义版本的URLSpan,它不能启用TextPaint的"下划线"属性:

    private class URLSpanNoUnderline extends URLSpan {
        public URLSpanNoUnderline(String url) {
            super(url);
        }
        @Override public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(false);
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案假定跨度的文本与URL相同,这是基本http://链接的情况.但是,Linkify非常智能,可以将电话号码(212)555-1212转换为URL"tel:2125551212".应该传递`new URLSpanNoUnderline`调用`span.getURL()`以保留此信息,否则会生成导致异常的错误链接.我已将此建议的解决方案放在编辑队列中以供您回答,因为我自己没有编辑权限. (9认同)
  • 不适合我.它在Line Spannable s =(Spannable)textView.getText();给出了类强制转换异常. (7认同)
  • 只需用Spannable s = new SpannableString(textView.getText())替换该行; (5认同)
  • 当我从 TextView 中删除 `android:autoLink="web"` 后它就可以工作了。谢谢。 (3认同)
  • 有什么办法可以使用`android:autoLink` 属性来完成这项工作吗?否则,您似乎必须为内置功能创建自己的 onclick 方法。 (2认同)

Adr*_*ter 27

给出textView和内容:

TextView textView = (TextView) findViewById(R.id.your_text_view_id);
String content = "your <a href='http://some.url'>html</a> content";
Run Code Online (Sandbox Code Playgroud)

以下是从超链接中删除下划线的简明方法:

Spannable s = (Spannable) Html.fromHtml(content);
for (URLSpan u: s.getSpans(0, s.length(), URLSpan.class)) {
    s.setSpan(new UnderlineSpan() {
        public void updateDrawState(TextPaint tp) {
            tp.setUnderlineText(false);
        }
    }, s.getSpanStart(u), s.getSpanEnd(u), 0);
}
textView.setText(s);
Run Code Online (Sandbox Code Playgroud)

这是基于robUx4建议的方法.

为了使链接可以点击,您还需要调用:

textView.setMovementMethod(LinkMovementMethod.getInstance());
Run Code Online (Sandbox Code Playgroud)

  • 如果你试图从资源中获取一个字符串,这不起作用,所以`String content = getResources().getString(R.string.content);`包含一个链接不再有效. (6认同)

sma*_*871 11

这是Kotlin扩展函数:

fun TextView.removeLinksUnderline() {
    val spannable = SpannableString(text)
    for (u in spannable.getSpans(0, spannable.length, URLSpan::class.java)) {
        spannable.setSpan(object : URLSpan(u.url) {
            override fun updateDrawState(ds: TextPaint) {
                super.updateDrawState(ds)
                ds.isUnderlineText = false
            }
        }, spannable.getSpanStart(u), spannable.getSpanEnd(u), 0)
    }
    text = spannable
}
Run Code Online (Sandbox Code Playgroud)

用法:

txtView.removeLinksUnderline()    
Run Code Online (Sandbox Code Playgroud)

  • 使用: `ds.color = ContextCompat.getColor(this@MainActivity, R.color.myColor)` 更改链接文本颜色 (2认同)

小智 10

UnderlineSpan 已经存在,但只能设置下划线.

Another solution is to add a no underline span on each existing URLSpan. Thus the underline state is disabled just before painting. This way you keep your URLSpan (possibly custom) classes and all other styles set elsewhere.

public class NoUnderlineSpan extends UnderlineSpan {
    public NoUnderlineSpan() {}

    public NoUnderlineSpan(Parcel src) {}

    @Override
    public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

Here is how you set it without removing the existing URLSpan object:

URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
for (URLSpan span: spans) {
    int start = s.getSpanStart(span);
    int end = s.getSpanEnd(span);
    NoUnderlineSpan noUnderline = new NoUnderlineSpan();
    s.setSpan(noUnderline, start, end, 0);
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我已经实现了一个在我看来更优雅的解决方案。我做了一个定制TextView。这样您就不需要为每个TextView超链接执行额外的代码。

package com.example.view;

import android.content.Context;
import android.support.v7.widget.AppCompatTextView;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.URLSpan;
import android.util.AttributeSet;

import com.example.utils.UrlSpanNoUnderline;

public class TextViewNoUnderline extends AppCompatTextView {
    public TextViewNoUnderline(Context context) {
        this(context, null);
    }

    public TextViewNoUnderline(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    public TextViewNoUnderline(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setSpannableFactory(Factory.getInstance());
    }

    private static class Factory extends Spannable.Factory {
        private final static Factory sInstance = new Factory();

        public static Factory getInstance() {
            return sInstance;
        }

        @Override
        public Spannable newSpannable(CharSequence source) {
            return new SpannableNoUnderline(source);
        }
    }

    private static class SpannableNoUnderline extends SpannableString {
        public SpannableNoUnderline(CharSequence source) {
            super(source);
        }

        @Override
        public void setSpan(Object what, int start, int end, int flags) {
            if (what instanceof URLSpan) {
                what = new UrlSpanNoUnderline((URLSpan) what);
            }
            super.setSpan(what, start, end, flags);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以及 UrlSpanNoUnderline 的代码:

package com.jankstudios.smmagazine.utils;

import android.text.TextPaint;
import android.text.style.URLSpan;

public class UrlSpanNoUnderline extends URLSpan {
    public UrlSpanNoUnderline(URLSpan src) {
        super(src.getURL());
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setUnderlineText(false);
    }
}
Run Code Online (Sandbox Code Playgroud)