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)起來也不太難(起碼我認(rèn)為的實(shí)現(xiàn)方式是有許多種的),今天就講解一下如何使用自定義屬性來實(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>
其中需要說明的是,自定義屬性文件的根節(jié)點(diǎn)頁是<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類型,也就是說當(dāng)前定義的屬性取值只能為boolean類型的,format可以表示的的類型有好多種,最常見的如:string,boolean,integer,dimension,reference等這,里就不再詳細(xì)講解了,如果誰有疑問,可以自己動(dòng)手問問度娘,她知道的比我多,呵呵
二、使用自定義屬性
在attrs.xml文件中定義好了屬性,就可以在布局文件中使用了,接下來看看在布局文件中如何使用自定義屬性吧,代碼如下:
<?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)操作
完成自定義屬性文件之后,我們就來為控件添加自定義的屬性了,自定義控件我認(rèn)為最簡(jiǎn)單的實(shí)現(xiàn)就是使用繼承,在繼承的基礎(chǔ)上進(jìn)行擴(kuò)充來實(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); // 獲取文本顏色值,用來畫邊框的,便于和文本顏色匹配 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控件在屏幕上顯示出來大致可以歸納為三大步驟,首先調(diào)用View控件的onMesure方法,其次調(diào)用View控件的onLayout方法,再次調(diào)用View控件的onDraw方法,所以我們只需要在draw方法中繪制出邊框就行了,繪制邊框的步驟很簡(jiǎn)單,代碼注釋也很詳細(xì),就不再詳細(xì)講解了
最后運(yùn)行一下程序來看一下效果圖吧,呵呵
好了,今天的自定義屬性實(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屬性無效問題的解決方法
- android TextView不用ScrollViewe也可以滾動(dòng)的方法
- Android控件系列之TextView使用介紹
- Android 自定義TextView實(shí)現(xiàn)文本內(nèi)容自動(dòng)調(diào)整字體大小
相關(guān)文章
使用SignalR推送服務(wù)在Android的實(shí)現(xiàn) SignalA
SignalA是老外寫的用于實(shí)現(xiàn).net端推送消息至安卓端的實(shí)現(xiàn),支持版本為android 2.3或以上2014-07-07詳解Android Material設(shè)計(jì)中陰影效果的實(shí)現(xiàn)方法
這篇文章主要介紹了Android Material設(shè)計(jì)中陰影效果的實(shí)現(xiàn)方法,包括自定義陰影的輪廓和裁剪等,需要的朋友可以參考下2016-04-04Android開發(fā)實(shí)現(xiàn)的獲取sdcard大小及內(nèi)存大小工具類
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)的獲取sdcard大小及內(nèi)存大小工具類,涉及Android針對(duì)手機(jī)硬件SD卡及內(nèi)存相關(guān)操作技巧,需要的朋友可以參考下2017-11-11Android中ScrollView 滑到頭部或尾部可伸縮放大效果
最近做項(xiàng)目遇到這樣的需求S當(dāng)crollView 滑動(dòng)到頂部,不能在滑動(dòng)的時(shí)候,圖片可以下拉放大,松開又恢復(fù),滑到底部沒有內(nèi)容的時(shí)候,也有伸縮效果,下面通過實(shí)例代碼給大家介紹Android ScrollView 滑到頭部或尾部可伸縮放大功能,一起學(xué)習(xí)吧2017-03-03Android GSYVideoPlayer視頻播放器功能的實(shí)現(xiàn)
這篇文章主要介紹了Android GSYVideoPlayer視頻播放器功能的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03Android自定義View實(shí)現(xiàn)相機(jī)對(duì)焦框
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)相機(jī)對(duì)焦框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Android實(shí)現(xiàn)自動(dòng)變換大小的ViewPager
ViewPager使用適配器類將數(shù)據(jù)和view的處理分離,ViewPager的適配器叫PagerAdapter,這是一個(gè)抽象類,不能實(shí)例化,所以它有兩個(gè)子類:FragmentPagerAdapter 和 FragmentStatePagerAdapter,這兩個(gè)都是處理頁面為Fragment的情況2022-11-11Android仿硬幣轉(zhuǎn)動(dòng)微信紅包動(dòng)畫效果
項(xiàng)目需要研究了一下微信紅包動(dòng)畫,即硬幣轉(zhuǎn)動(dòng)的效果,原理其實(shí)就是三張不同角度的圖片利用AnimationDrawable幀動(dòng)畫進(jìn)行播放。下面通過本文給大家分享Android仿微信紅包動(dòng)畫效果,感興趣的朋友一起看看吧2017-12-12Android View.onMeasure方法詳解及實(shí)例
這篇文章主要介紹了Android View.onMeasure方法詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05Android中ArrayList和數(shù)組相互轉(zhuǎn)換
在我們?nèi)粘i_發(fā)中難免會(huì)要將ArrayList和數(shù)組相互轉(zhuǎn)換,那么如何才能相互轉(zhuǎn)換呢?下面跟著小編一起通過這篇文章學(xué)習(xí)學(xué)習(xí)。2016-08-08