Android UI設(shè)計(jì)系列之自定義TextView屬性實(shí)現(xiàn)帶下劃線的文本框(4)
在Android開發(fā)過程中,如果Android系統(tǒng)自帶的屬性不能滿足我們?nèi)粘i_發(fā)的需求,那么就需要我們給系統(tǒng)控件添加額外的屬性了。假如有個(gè)需求是實(shí)現(xiàn)帶下劃線的文本顯示(下劃線),如果不使用自定義屬性的話實(shí)現(xiàn)起來(lái)也不太難(起碼我認(rèn)為的實(shí)現(xiàn)方式是有許多種的),今天就講解一下如何使用自定義屬性來(lái)實(shí)現(xiàn)上述帶下劃線的文本框吧。還好Android中自定義屬性不是很復(fù)雜,也可以歸納為三步走吧。
老規(guī)矩,還是先貼出工程目錄吧:

一、添加屬性文件
在values文件夾中新建attrs.xml文件,在文件中新建屬性文件,代碼如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- 自定義屬性開始 --> <declare-styleable name="BorderTextView"> <attr name="layout_borders" format="boolean"></attr> <attr name="layout_borderLeft" format="boolean"></attr> <attr name="layout_borderTop" format="boolean"></attr> <attr name="layout_borderRight" format="boolean"></attr> <attr name="layout_borderBottom" format="boolean"></attr> </declare-styleable> <!-- 自定義屬性結(jié)束 --> </resources>
其中需要說(shuō)明的是,自定義屬性文件的根節(jié)點(diǎn)頁(yè)是<resources>,在根節(jié)點(diǎn)內(nèi)創(chuàng)建你所需要的屬性值,自定義屬性的節(jié)點(diǎn)是以<declare-styleable>開始的,它表示的是個(gè)屬性集可以包含眾多屬性,其中name="BorderTextView"是屬性集名。接著在<declare-styleable>中定義我們需要的以<attr>為節(jié)點(diǎn)的屬性,attr表示屬性的意思name表示當(dāng)前屬性的名稱,format表示的是屬性值的類型,例如我們當(dāng)前定義的屬性類型為boolean類型,也就是說(shuō)當(dāng)前定義的屬性取值只能為boolean類型的,format可以表示的的類型有好多種,最常見的如:string,boolean,integer,dimension,reference等這,里就不再詳細(xì)講解了,如果誰(shuí)有疑問,可以自己動(dòng)手問問度娘,她知道的比我多,呵呵
二、使用自定義屬性
在attrs.xml文件中定義好了屬性,就可以在布局文件中使用了,接下來(lái)看看在布局文件中如何使用自定義屬性吧,代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:greendroid="http://schemas.android.com/apk/res/com.llew.e" android:orientation="vertical" android:layout_width="fill_parent" android:background="#ffffff" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dip" android:text="@string/hello" android:textColor="#000000" /> <com.llew.e.view.wedgit.BorderTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="左側(cè)帶有邊框" android:layout_margin="10dip" greendroid:layout_borderLeft="true" android:textSize="20sp" android:textColor="#aabbcc"> </com.llew.e.view.wedgit.BorderTextView> <com.llew.e.view.wedgit.BorderTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="頂部帶有邊框" android:layout_margin="10dip" greendroid:layout_borderTop="true" android:textSize="20sp" android:textColor="#bbccaa"> </com.llew.e.view.wedgit.BorderTextView> <com.llew.e.view.wedgit.BorderTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="右側(cè)帶有邊框" android:layout_margin="10dip" greendroid:layout_borderRight="true" android:textSize="20sp" android:textColor="#ccaabb"> </com.llew.e.view.wedgit.BorderTextView> <com.llew.e.view.wedgit.BorderTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="底部帶有邊框" android:layout_margin="10dip" greendroid:layout_borderBottom="true" android:textSize="20sp" android:textColor="#abcabc"> </com.llew.e.view.wedgit.BorderTextView> <com.llew.e.view.wedgit.BorderTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="四周帶有邊框" android:layout_margin="10dip" greendroid:layout_borders="true" android:textSize="20sp" android:textColor="#cbacba"> </com.llew.e.view.wedgit.BorderTextView> </LinearLayout>
使用自定義控件也很簡(jiǎn)單就是包名+自定義控件名,為了使用我們自定義的屬性,必須在布局文件的根節(jié)點(diǎn)中加上xmlns:greendroid="http://schemas.android.com/apk/res/com.llew.e"這句話,其中xmlns:greendroid表示的是命名空間名稱,greendroid只是個(gè)名字是我們使用自定義屬性的前綴,可以隨便取值(只要不是android就行了),com.llew.e是在manifest中的package的對(duì)應(yīng)值,使用自定義屬性就想代碼中的那樣:greendroid:layout_borderLeft="true",(*^__^*) 嘻嘻……,是不是可簡(jiǎn)單?
三、根據(jù)自定義屬性值做相應(yīng)操作
完成自定義屬性文件之后,我們就來(lái)為控件添加自定義的屬性了,自定義控件我認(rèn)為最簡(jiǎn)單的實(shí)現(xiàn)就是使用繼承,在繼承的基礎(chǔ)上進(jìn)行擴(kuò)充來(lái)實(shí)現(xiàn)我們所要的功能,所以為了實(shí)現(xiàn)帶邊框的文本組件,我就直接繼承了TextView組件,在它的基礎(chǔ)上進(jìn)行擴(kuò)充了,代碼如下:
public class BorderTextView extends TextView {
/**
* 四周是否帶有邊框【true:四周帶有邊框】【false:四周不帶邊框】
*/
boolean borders = false;
/**
* 左邊是否帶有邊框【true:左側(cè)帶有邊框】【false:左側(cè)不帶邊框】
*/
boolean borderLeft = false;
/**
* 頂部是否帶有邊框【true:頂部帶有邊框】【false:底部不帶邊框】
*/
boolean borderTop = false;
/**
* 右側(cè)是否帶有邊框【true:右側(cè)帶有邊框】【false:右側(cè)不帶邊框】
*/
boolean borderRight = false;
/**
* 底部是否帶有邊框【true:底部帶有邊框】【false:底部不帶邊框】
*/
boolean borderBottom = false;
/**
* 邊框顏色
*/
String textColor = "#ff000000";
public BorderTextView(Context context) {
this(context, null);
}
public BorderTextView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.textViewStyle);
}
public BorderTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// 獲取自定義屬性集
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.BorderTextView);
// 是否設(shè)置全部邊框,默認(rèn)為false
borders = typedArray.getBoolean(
R.styleable.BorderTextView_layout_borders, false);
// 是否設(shè)置左側(cè)邊框,默認(rèn)為false
borderLeft = typedArray.getBoolean(
R.styleable.BorderTextView_layout_borderLeft, false);
// 是否設(shè)置頂部邊框,默認(rèn)為false
borderTop = typedArray.getBoolean(
R.styleable.BorderTextView_layout_borderTop, false);
// 是否設(shè)置右側(cè)邊框,默認(rèn)為false
borderRight = typedArray.getBoolean(
R.styleable.BorderTextView_layout_borderRight, false);
// 是否設(shè)置底部邊框,默認(rèn)為false
borderBottom = typedArray.getBoolean(
R.styleable.BorderTextView_layout_borderBottom, false);
// 獲取文本顏色值,用來(lái)畫邊框的,便于和文本顏色匹配
textColor = attrs.getAttributeValue(
"http://schemas.android.com/apk/res/android", "textColor");
typedArray.recycle();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
// 創(chuàng)建畫筆
Paint paint = new Paint();
// 獲取該畫筆顏色
int color = paint.getColor();
// 設(shè)置畫筆顏色
paint.setColor(Color.parseColor(textColor));
// 如果borders為true,表示左上右下都有邊框
if (borders) {
canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint);
canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);
canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1,
this.getHeight() - 1, paint);
canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1,
this.getHeight() - 1, paint);
} else {
if (borderLeft) {
// 畫左邊框線
canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint);
}
if (borderTop) {
// 畫頂部邊框線
canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);
}
if (borderRight) {
// 畫右側(cè)邊框線
canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1,
this.getHeight() - 1, paint);
}
if (borderBottom) {
// 畫底部邊框線
canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1,
this.getHeight() - 1, paint);
}
}
// 設(shè)置畫筆顏色歸位
paint.setColor(color);
}
} 其實(shí)給BorderTextView添加邊框也是很簡(jiǎn)單,原理就是其draw方法中繪畫出邊框罷,我們都知道每一個(gè)View控件在屏幕上顯示出來(lái)大致可以歸納為三大步驟,首先調(diào)用View控件的onMesure方法,其次調(diào)用View控件的onLayout方法,再次調(diào)用View控件的onDraw方法,所以我們只需要在draw方法中繪制出邊框就行了,繪制邊框的步驟很簡(jiǎn)單,代碼注釋也很詳細(xì),就不再詳細(xì)講解了
最后運(yùn)行一下程序來(lái)看一下效果圖吧,呵呵

好了,今天的自定義屬性實(shí)現(xiàn)帶邊框的TextView控件就講解完了,謝謝大家的閱讀。
源碼下載:Android UI實(shí)現(xiàn)帶下劃線的文本框
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android自定義TextView實(shí)現(xiàn)文字傾斜效果
- Android 讓自定義TextView的drawableLeft與文本一起居中
- 自定義TextView跑馬燈效果可控制啟動(dòng)/停止/速度/焦點(diǎn)
- android TextView設(shè)置中文字體加粗實(shí)現(xiàn)方法
- Android TextView設(shè)置背景色與邊框的方法詳解
- android實(shí)現(xiàn)上下滾動(dòng)的TextView
- android TextView多行文本(超過3行)使用ellipsize屬性無(wú)效問題的解決方法
- android TextView不用ScrollViewe也可以滾動(dòng)的方法
- Android控件系列之TextView使用介紹
- Android 自定義TextView實(shí)現(xiàn)文本內(nèi)容自動(dòng)調(diào)整字體大小
相關(guān)文章
詳解Android冷啟動(dòng)實(shí)現(xiàn)APP秒開的方法
這篇文章給大家介紹的是Android冷啟動(dòng)實(shí)現(xiàn)APP秒開的方法,對(duì)大家日常開發(fā)APP還是很實(shí)用的,有需要的可以參考借鑒。2016-08-08
Android 如何使用SQLite保存數(shù)據(jù)
對(duì)于重復(fù)數(shù)據(jù)或結(jié)構(gòu)化數(shù)據(jù)(例如聯(lián)系信息),將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)是理想選擇,SQL 數(shù)據(jù)庫(kù)的主要原則之一是架構(gòu),即數(shù)據(jù)庫(kù)組織方式的正式聲明,本篇文章介紹在 Android 上使用 SQLite 數(shù)據(jù)庫(kù),感興趣的朋友一起看看吧2024-03-03
Android實(shí)現(xiàn)音樂播放進(jìn)度條傳遞信息的兩種方式(在service和activity中)
這篇文章主要介紹了Android:在service和activity之中,實(shí)現(xiàn)音樂播放進(jìn)度條傳遞信息的兩種方式,MediaPlayer做音樂播放器采坑以及解決辦法,需要的朋友可以參考下2020-05-05
使用RecyclerView實(shí)現(xiàn)瀑布流高度自適應(yīng)
這篇文章主要為大家詳細(xì)介紹了使用RecyclerView實(shí)現(xiàn)瀑布流高度自適應(yīng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Android神兵利器之Image Asset Studio的實(shí)現(xiàn)
這篇文章主要介紹了Android神兵利器之Image Asset Studio的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Android開發(fā)注解排列組合出啟動(dòng)任務(wù)ksp
這篇文章主要為大家介紹了Android開發(fā)注解排列組合出啟動(dòng)任務(wù)ksp示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Android中RecyclerView實(shí)現(xiàn)滑動(dòng)刪除與拖拽功能
這篇文章主要使用了RecyclerView的ItemTouchHelper類實(shí)現(xiàn)了Item的拖動(dòng)和刪除功能,ItemTouchHelper是v7包下的一個(gè)類,下面來(lái)看看詳細(xì)的介紹吧,需要的朋友可以參考學(xué)習(xí)。2017-02-02
kotlin中數(shù)據(jù)類重寫setter getter的正確方法
這篇文章主要給大家介紹了關(guān)于kotlin中數(shù)據(jù)類重寫setter getter的正確方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用kotlin具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-06-06

