Android UI编程之自定义控件——可高亮显示的TextView
概述:
? ? 如果你想要在一個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<SubMatchModel> 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<SubMatchModel>來記錄它:
/*** 獲得一個字符串中匹配正則的子字符集* @author Q-WHai* 2015-3-12*/public static List<SubMatchModel> getMatchString(String str, String exp) {Pattern p = Pattern.compile(exp); // 在這里,編譯 成一個正則Matcher m;m = p.matcher(str); // 獲得匹配List<SubMatchModel> models = new ArrayList<SubMatchModel>();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("我的郵箱地址是:abcdef@126.com,你的郵箱地址是:123548@qq.com");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究竟是怎么樣的呢?
例如我的代碼就是這樣的:
<?xml version="1.0" encoding="utf-8"?> <resources><declare-styleable name="LightTextView"><attr name="text" format="string" /><attr name="isMatch" format="boolean" /><attr name="decForeground" format="boolean" /><attr name="decbackground" format="boolean" /><attr name="backgroundColor" format="reference|color" /><attr name="foregroundColor" format="reference|color" /></declare-styleable></resources>
注意事項:
這里有一些地方需要我們注意一下。
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文件中需要包含程序名:
一定要有上面的被紅色框框出來的兩個部分。在紅色框中又被框出來兩個部分也是需要注意的。前者為你后面要使用的自定義屬性的名稱,后者為你目前的程序包名,而不能使用你自定義控件所在的包。
源碼下載:
以上就是全部的講解,如果大家還有什么不太明白的地方,歡迎移步到我的源碼地址進行下載。
http://download.csdn.net/detail/u013761665/8496945
總結
以上是生活随笔為你收集整理的Android UI编程之自定义控件——可高亮显示的TextView的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在cmd中使用指令来执行jar包
- 下一篇: 在Windows上使用putty连接一台