2010-11-04 38 views
71

Tôi đang sử dụng hai textview để hiển thị các liên kết từ cơ sở dữ liệu, tôi quản lý để thay đổi màu sắc liên kết nhưng tôi muốn loại bỏ các gạch dướiRemove gạch dưới từ các liên kết trong TextView - Android

email.setText(c.getString(5)); 
    website.setText(c.getString(6)); 
    Linkify.addLinks(email, Linkify.ALL); 
    Linkify.addLinks(website, Linkify.ALL); 

Tôi có thể làm điều đó từ XML hoặc Mã ?

Trả lời

182

Bạn có thể làm điều đó bằng mã bằng cách tìm và thay thế các trường hợp URLSpan với các phiên bản không gạch dưới. Sau khi bạn gọi Linkify.addLinks(), gọi hàm stripUnderlines() dán dưới đây trên mỗi TextView của bạn:

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

Điều này đòi hỏi một phiên bản tùy biến của URLSpan mà không cho phép của TextPaint "gạch chân" bất động sản:

private class URLSpanNoUnderline extends URLSpan { 
     public URLSpanNoUnderline(String url) { 
      super(url); 
     } 
     @Override public void updateDrawState(TextPaint ds) { 
      super.updateDrawState(ds); 
      ds.setUnderlineText(false); 
     } 
    } 
+9

giải pháp này giả định văn bản của nhịp cũng giống như URL, đó là trường hợp cho liên kết http: // cơ bản. Tuy nhiên, Linkify là thông minh và chuyển đổi một số điện thoại như (212) 555-1212 vào URL 'tel: 2125551212'. Cuộc gọi 'URLSpanNoUnderline' mới sẽ được chuyển qua' span.getURL() 'để giữ lại thông tin này, nếu không bạn tạo các liên kết xấu gây ra ngoại lệ khi được nhấp. Tôi đã đặt giải pháp được đề xuất này trong hàng đợi chỉnh sửa cho câu trả lời của bạn vì tôi không có quyền chỉnh sửa. –

+0

Chúc mừng Mike. Tôi đã chấp thuận chỉnh sửa của bạn, lần đầu tiên tôi từng thấy * hộp thoại chỉnh sửa đó, hy vọng nó hoạt động. –

+0

"Văn bản của span giống với URL" nghĩa là gì? –

10

UnderlineSpan đã tồn tại, nhưng chỉ có thể đặt gạch dưới.

Một giải pháp khác là thêm khoảng không gạch dưới trên mỗi URLSpan hiện tại. Do đó, trạng thái gạch dưới bị vô hiệu hóa ngay trước khi vẽ. Bằng cách này, bạn giữ các lớp học URLSpan (có thể tùy chỉnh) và tất cả các kiểu khác được đặt ở nơi khác.

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

    public NoUnderlineSpan(Parcel src) {} 

    @Override 
    public void updateDrawState(TextPaint ds) { 
     ds.setUnderlineText(false); 
    } 
} 

Đây là cách bạn cài đặt nó mà không cần tháo đối tượng hiện URLSpan:

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

Cho một TextView và nội dung:

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

Dưới đây là một cách súc tích để loại bỏ gạch dưới từ các siêu liên kết :

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

Điều này dựa trên phương pháp được đề xuất bởi robUx4.

Để thực hiện các liên kết có thể click bạn cũng cần phải gọi:

textView.setMovementMethod(LinkMovementMethod.getInstance()); 
+3

điều này không hoạt động nếu bạn cố gắng lấy chuỗi từ tài nguyên, vì vậy 'String content = getResources(). GetString (R.string.content);' bao gồm một liên kết không còn hoạt động nữa. –

+0

Làm cách nào có thể? Một String không biết nó bắt nguồn từ đâu. Phải có sự khác biệt trong nội dung Chuỗi. –

+0

không chắc chắn lý do tại sao nhưng nó không hiển thị url khi tôi gọi chuỗi từ 'res/values ​​/ strings.xml' chứa chính xác điều tương tự như ví dụ. Bạn có thể kiểm tra cuối cùng của bạn? –

2

Bất cứ khi nào, hãy cố gắng URL remove nhấn mạnh với spannable là tôi đề nghị chỉ những điều sau:

1>Tạo Lớp tùy chỉnh:

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

Điều này yêu cầu phiên bản tùy chỉnh URLSpan mà không cho phép của TextPaint "gạch chân" bất động sản

2>setSpan với văn bản spannable:

spannableText.setSpan(new URLSpanNoUnderline(UrlText), 0, UrlText.length() , 0); 

Ở đây, spannableText là đối tượng của SpannableString ... !! !

+0

Đây là giải pháp tốt nhất và chỉ làm việc cho tôi – GuilhE

0
public void setView() 
{ 
TextView t=(TextView) findViewById(R.id.textView3); 
     t.setText(Html.fromHtml("<a href=http://www.urdusms.net > UrduSMS ")); 
     t.setTextColor(Color.BLACK); 
     t.setGravity(Gravity.CENTER); 
     t.setMovementMethod(LinkMovementMethod.getInstance()); 

     Spannable s = (Spannable) t.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 URLSpanline_none(span.getURL()); 
       s.setSpan(span, start, end, 0); 
      } 
     t.setText(s); 
} 
//inner class is  
private class URLSpanline_none extends URLSpan { 
      public URLSpanline_none(String url) { 
       super(url); 
      } 
      @Override public void updateDrawState(TextPaint ds) { 
       super.updateDrawState(ds); 
       ds.setUnderlineText(false); 
      } 
     } 
1

Tôi đã triển khai giải pháp theo ý kiến ​​của mình, thanh lịch hơn. Tôi đã thực hiện tùy chỉnh TextView. Bằng cách này, bạn không cần phải thực thi mã bổ sung cho mỗi TextView với siêu liên kết.

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

Và mã cho 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); 
    } 
} 
0

Nếu bạn chỉ muốn các văn bản và đừng bận tâm về những liên kết URL

này sẽ STRIP vào liên kết nhưng GIỮ văn bản

private Spannable stripLinks(String content) { 
    Spannable s = new SpannableString(content); 
    URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class); 
    for (URLSpan span : spans) { 
     s.removeSpan(span); 
    } 

    return s; 
} 

không lớp học bổ sung cần thiết

String content = "<a href='http://stackoverflow.com'>Stack Overflow</a> Rocks!"; 
textView.setText(stripLinks(content)); 
1

Nếu bạn đang sử dụng tài sản autolink TextView và bạn muốn loại bỏ gạch chân bạn có thể sử dụng nó:

Thứ nhất, mở rộng UnderlineSpan và loại bỏ gạch dưới:

public class NoUnderlineSpan extends UnderlineSpan { 

    @Override 
    public void updateDrawState(TextPaint ds) { 
     ds.setUnderlineText(false); 
    } 
} 

Thứ hai, tạo và thể hiện NoUnderlineSpan, tạo Spannable từ văn bản String và đặt khoảng cách thành spannable:

NoUnderlineSpan mNoUnderlineSpan = new NoUnderline(); 
if (yourTextView.getText() instanceof Spannable) { 
    Spannable s = (Spannable) yourTextView.getText(); 
    s.setSpan(mNoUnderlineSpan, 0, s.length(), Spanned.SPAN_MARK_MARK); 
} 

tham khảo: http://prog3.com/sbdm/blog/maosidiaoxian/article/details/39156563

0

Gạch chân trong android: Tự động liên kết thể được gỡ bỏ bằng android: textAllCaps = "true"android: textIsSelectable = "false"

<TextView 
    android:autoLink="phone" 
    android:text="070 300 1155" 
    android:textAllCaps="true" 
    android:textIsSelectable="false" 
    /> 
0

Đây là Phương thức của tôi

public static void removeUnderlines(Spannable p_Text) { 
      if (p_Text != null && p_Text.toString().length() > 0) { 
       URLSpan[] spans = p_Text.getSpans(0, p_Text.length(), URLSpan.class); 

       for (URLSpan span : spans) { 
        int start = p_Text.getSpanStart(span); 
        int end = p_Text.getSpanEnd(span); 
        p_Text.removeSpan(span); 
        span = new URLSpanNoUnderline(span.getURL()); 
        p_Text.setSpan(span, start, end, 0); 
       } 
      } 
     } 

Call It như thế này

AppController.removeUnderlines((Spannable) eventEmail.getText()); 

AppController là lớp ứng dụng của tôi, nơi tôi đặt phương pháp này để tôi có thể truy cập nó từ bất cứ nơi nào

Các vấn đề liên quan