Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android UI編程之自定義控件——可高亮顯示的TextView

Android UI編程之自定義控件——可高亮顯示的TextView

編輯:關於Android編程

概述:

如果你想要在一個TextView顯示一個被高亮顯示的子字符串。例如,我想讓123456789中的345被高亮顯示。注意,我這裡指的只高亮一部分,而不是全部高亮。你會怎麼做?我不知道會不會有一些初學者會想到的是,讓這些子字符串分部於不同的TextView,再對每個TextView進行單獨處理。當然,如果你已經是一個已經有一些經驗的開發者,那我想,你應該就不會再這樣去思考了。因為,Android已經給我封裝好了——SpannableStringBuilder。下面我就學習Android中對控件的一些封裝來封裝一個我們自己的TextView(既可在xml中設置也可在Java代碼中設置)。

 

實例效果圖:

這裡其實有兩個LightTextView。第一個是匹配所有的郵箱,第二個是匹配所有的數字。具體細節,大家可以在博客的最後下載源碼進行查看。

\

 

實例功能介紹:

1.設置文本內容

2.設置需要進行匹配的正則表達式

3.設置匹配出來的子字符串的前景色

4.設置匹配出來的子字符串的背景色

5.設置是否顯示前景色

6.設置是否顯示背景色

7.設置是否部署以上設置

 

實例示范講解:

1.在Java代碼中去實現控件屬性的設置

其實使用Java代碼來設置控件的屬性,無疑是簡單的。因為它,只是需要對外封裝出一些可用的接口即可。例如下面這樣:

 

/**
     * 設置背景色
     * 2015-3-12
     */
    private int mBackColor;
    public void setBackColor(int color) {
        mBackColor = color;
    }
是不是很簡單?

 

當前,Java代碼在這方面與attrs相比,的確是要簡單一些。不過,程序的關鍵還是要依靠Java代碼來支撐的。例如下面這個代碼片段:

 

private void showForeBackground() {
        SpannableStringBuilder styleBuilder = new SpannableStringBuilder(mText); // 包裝字體內容
        
        if (mDecbackground) {
            for (int i = 0; i < matchedText.size(); i++) {
                styleBuilder.setSpan(new BackgroundColorSpan(mBackColor), matchedText.get(i).getStart(), matchedText.get(i).getEnd(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        
        if (mDecForeground) {
            for (int i = 0; i < matchedText.size(); i++) {
                styleBuilder.setSpan(new ForegroundColorSpan(mForeColor), matchedText.get(i).getStart(), matchedText.get(i).getEnd(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        
        setText(styleBuilder);
    }
可能大家看到一些變量和函數名的時候已經猜測到了這個代碼段的功能了。它就是設置我們需要對子字符串高亮的部分。這裡有一個變量需要注意matchedText,它在代碼中的定義如下:

 

 

private List matchedText = null;
是的,這是一個List,那裡面的SubMatchModel是什麼呢?這是一個我們自己封裝好了的Model。它的功能是記錄我們在匹配字符串的過程中,遇到的字符集(當前一個Model也就只對記錄一個子字符了,所以這裡才會是List)。好了,那現在就讓我們看看它裡面的內容吧:

 

 

public class SubMatchModel {

    private String subString;
    
    private int start;
    
    private int end;

    public String getSubString() {
        return subString;
    }

    public void setSubString(String subString) {
        this.subString = subString;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }
    
}
這裡只有三個成員變量

 

subString:記錄匹配到的子字符串

start:這個子字符串的開始位置

end:這個子字符串的結束位置

 

下面就是一個基本匹配的過程,並使用List來記錄它:

 

/**
     * 獲得一個字符串中匹配正則的子字符集
     * @author Q-WHai
     * 2015-3-12
     */
    public static List getMatchString(String str, String exp) {
        Pattern p = Pattern.compile(exp); // 在這裡,編譯 成一個正則
        Matcher m;
        m = p.matcher(str); // 獲得匹配
        List models = new ArrayList();
        SubMatchModel model = null;
        
        while(m.find()) {
            model = new SubMatchModel();
            
            model.setSubString(m.group());
            model.setStart(m.start());
            model.setEnd(m.end());
            
            models.add(model);
        }
        
        return models;
    }

 

 

使用示范:

 

private LightTextView mShowLightTextView = null;

 

 

private void resetWidgets() {
        mShowLightTextView.setIsMatchOrNot(true);
        mShowLightTextView.setText(我的郵箱地址是:[email protected],你的郵箱地址是:[email protected]);
        mShowLightTextView.setRegularExp(Utils.getMatchEmailString());
        mShowLightTextView.setBackColor(Color.BLUE);
        mShowLightTextView.setForeColor(Color.RED);
        mShowLightTextView.setDecbackground(true);
        mShowLightTextView.setDecForeground(true);
        mShowLightTextView.show();
    }
大家可以看到上面最後一個方法,show(),是不是顯示這個LigthTextView呢?不是的,它只是把之前對LightTextView的一些設置部署到這個LightTextView上來而已。

 

 

2.自定義屬性attrs的使用

看了上面對LightTextView的一些屬性設置和部署,是不是感覺有一點復雜?當然,這裡要說它復雜和之前我說Java來寫比較簡單的說法不矛盾,因為這兩者之間沒有什麼關系。如果非要說上一些關系,我想應該是得失平衡吧。就像我們要把程序寫得簡單了,那麼用戶那邊可能就會比較復雜,如果想要讓用戶使用起來簡單,那程序中就會使用以一些比較復雜的邏輯。這裡也是這樣的。如果想要讓外部對其調用時比較簡單,那麼裡面的設置肯定是比較繁瑣的,如果想要讓內部的代碼簡單一些,那麼對外的內容就會比較繁瑣了。說了這麼多,那麼使用attrs究竟是怎麼樣的呢?

例如我的代碼就是這樣的:

 




    
        
        
        
        
        
        
    

 

 

注意事項:

這裡有一些地方需要我們注意一下。

1.在Java代碼的構造器中去實現以下方法:

 

private void init(TypedArray array) {
        mText = array.getString(R.styleable.LightTextView_text);
        mIsMatch = array.getBoolean(R.styleable.LightTextView_isMatch, true);
        mDecForeground = array.getBoolean(R.styleable.LightTextView_decForeground, false);
        mDecbackground = array.getBoolean(R.styleable.LightTextView_decbackground, false);
        mForeColor = array.getColor(R.styleable.LightTextView_foregroundColor, Color.BLACK);
        mBackColor = array.getColor(R.styleable.LightTextView_backgroundColor, Color.WHITE);
    }

 

在構造器中調用示范:

 

public LightTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.LightTextView);
        init(mTypedArray);
    }

 

2.在xml文件中需要包含程序名:

\
一定要有上面的被紅色框框出來的兩個部分。在紅色框中又被框出來兩個部分也是需要注意的。前者為你後面要使用的自定義屬性的名稱,後者為你目前的程序包名,而不能使用你自定義控件所在的包。

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved