天天看點

TextView的日常使用技巧

Textview在日常開發工作中使用非常頻繁,在這裡簡單總結一下其比較重要的用法。目标是設定textview的中一段文字的顯示屬性,例如指定文字要下劃線顯示(@XXX、#XXX#),文字替換成圖檔,文字加重、變色、變大等。

實作的基本思路都是将指定的文字找出來,然後用實作Spananble接口的子類覆寫,即可。

Spananble隻是一個接口,它的繼承關系是:Spananble->Spanned->CharSequence

因為Spannable繼承于CharSequence接口,因而,TextView可以直接setText,Spannable的實作類:Editable, SpannableString, SpannableStringBuilder 。

Spannable中有提供public abstract void setSpan (Object what, int start, int end, int flags) 方法,來設定被替換部分要顯示的樣式

其中參數Object what 又必須是 android.text.style.CharacterStyle 的實作子類,就是它決定顯示的樣式,例如實作下劃線的UrlSpan,實作改變字型顔色的ForegroundColorSpan,實作改變字型大小的AbsoluteSizeSpan,實作替換成圖檔的ImageSpan等。下面我會總結幾種常用的用法:

1、改變文字的大小以及顔色:

Java代碼 收藏代碼

String str = "This is testing text!"  
int start =str.indexOf("testing");  
int end = start + "testing ".length();  
SpannableStringBuilder style = new SpannableStringBuilder(str);  
int size = 20;  //20px  
style.setSpan(new AbsoluteSizeSpan(size), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);    
int color = 0xff0000; //設定指定位置文字的顔色   
style.setSpan(new ForegroundColorSpan(color), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);        
...  
  
textView.setText(style);        
2、實作多字元串的動态處理:      

Xml代碼 收藏代碼

string.xml:

這是一個數字:%1d,這又是成都為3的字元串:%3$s

Java代碼 收藏代碼

String text = String.format(getResources().getString(R.string.testing), 1, 22, "三個字");  
  
 int index[] = new int[3];    
 index[0] = text.indexOf("1");    
 index[1] = text.indexOf("22");    
 index[2] = text.indexOf("三個字");    
    
 SpannableStringBuilder style=new SpannableStringBuilder(text);       
 style.setSpan(new ForegroundColorSpan(Color.RED),index[0],index[0]+1,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);        
 style.setSpan(new ForegroundColorSpan(Color.RED),index[1],index[1]+2,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);        
 style.setSpan(new BackgroundColorSpan(Color.RED),index[2],index[2]+3,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);        
 textView.setText(style);        

在項目開發中,我們經常需要把多個字元串進行拼接,用上面的方式處理,并結合起來使用,可以避免很多Textview的拼接!

3、實作超連結效果:

第一種簡單做法:當文字中出現URL、E-mail、電話号碼等的時候,可以将TextView的android:autoLink屬性設定為相應的的值,也可以是所有的類型都都響應:android:autoLink=“all”,最後在java代碼裡,對指定的textView.setAutoLinkMask(Linkify.ALL);

第二種自定義做法:盡管第一種做法簡單,但都是預設調用,不能自定義跳轉,像微網誌的@XXX ,#XXX#這類的特殊文字的響應,需要指定處理的視圖。我們一般可以這樣子實作:

(1)我們先指定特定字元串響應點選:

Java代碼 收藏代碼

SpannableStringBuilder style = new SpannableStringBuilder("call: 110");    
style.setSpan(new StyleSpan(Typeface.BOLD), 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    
style.setSpan(new URLSpan("110"), 6, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    
textView.setText(style);    
textView.setMovementMethod(LinkMovementMethod.getInstance());        

(2)更改響應點選的方式:

URLSpan是我們常用的文字超連結控件,但是預設都會自帶下劃線,并不是太美觀。有官方API文檔可知,URLSpan繼承自 ClickableSpan , 因而我們可以通過繼承 ClickableSpan 并重寫其實作的方法,即可實作自定義跳轉控制,以及外觀樣式的控件了。

Java代碼 收藏代碼

public class URLSpanNoUnderline extends ClickableSpan {  
    private final String mURL;  
    public URLSpanNoUnderline(String url) {  
        mURL = url;  
    }  
  
    public String getURL() {  
        return mURL;  
    }  
  
    @Override  
    public void onClick(View widget) {  
        Uri uri = (Uri) widget.getTag();  
        if(uri!=null) {  
            final Context context = widget.getContext();  
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);  
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
            intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());  
            context.startActivity(intent);  
        }  
    }  
    @Override  
    public void updateDrawState(TextPaint ds) {  
        super.updateDrawState(ds);  
        ds.setUnderlineText(false);  //取消下劃線  
        ds.setColor(0xff0066ff);     //指定文字顔色  
        //ds.setTextSize(ds.getTextSize()*1.1F);  
    }  
}        
<activity  
            android:name=".activity.XXXActivity"  
            android:configChanges="keyboardHidden|orientation"  
            android:theme="@android:style/Theme.NoTitleBar" >  
            <intent-filter>  
                <action android:name="android.intent.action.VIEW" />  
  
                <category android:name="android.intent.category.DEFAULT" />  
                <category android:name="android.intent.category.BROWSABLE" />  
  
                <data  
                    android:host="_host"  
                    android:scheme="_scheme" />  
            </intent-filter>  
        </activity>