Android UI設計系列之自定義TextView屬性實現(xiàn)帶下劃線的文本框(4)
在Android開發(fā)過程中,如果Android系統(tǒng)自帶的屬性不能滿足我們?nèi)粘i_發(fā)的需求,那么就需要我們給系統(tǒng)控件添加額外的屬性了。假如有個需求是實現(xiàn)帶下劃線的文本顯示(下劃線),如果不使用自定義屬性的話實現(xiàn)起來也不太難(起碼我認為的實現(xiàn)方式是有許多種的),今天就講解一下如何使用自定義屬性來實現(xiàn)上述帶下劃線的文本框吧。還好Android中自定義屬性不是很復雜,也可以歸納為三步走吧。
老規(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> <!-- 自定義屬性結束 --> </resources>
其中需要說明的是,自定義屬性文件的根節(jié)點頁是<resources>,在根節(jié)點內(nèi)創(chuàng)建你所需要的屬性值,自定義屬性的節(jié)點是以<declare-styleable>開始的,它表示的是個屬性集可以包含眾多屬性,其中name="BorderTextView"是屬性集名。接著在<declare-styleable>中定義我們需要的以<attr>為節(jié)點的屬性,attr表示屬性的意思name表示當前屬性的名稱,format表示的是屬性值的類型,例如我們當前定義的屬性類型為boolean類型,也就是說當前定義的屬性取值只能為boolean類型的,format可以表示的的類型有好多種,最常見的如:string,boolean,integer,dimension,reference等這,里就不再詳細講解了,如果誰有疑問,可以自己動手問問度娘,她知道的比我多,呵呵
二、使用自定義屬性
在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="左側帶有邊框" 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="右側帶有邊框" 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é)點中加上xmlns:greendroid="http://schemas.android.com/apk/res/com.llew.e"這句話,其中xmlns:greendroid表示的是命名空間名稱,greendroid只是個名字是我們使用自定義屬性的前綴,可以隨便取值(只要不是android就行了),com.llew.e是在manifest中的package的對應值,使用自定義屬性就想代碼中的那樣:greendroid:layout_borderLeft="true",(*^__^*) 嘻嘻……,是不是可簡單?
三、根據(jù)自定義屬性值做相應操作
完成自定義屬性文件之后,我們就來為控件添加自定義的屬性了,自定義控件我認為最簡單的實現(xiàn)就是使用繼承,在繼承的基礎上進行擴充來實現(xiàn)我們所要的功能,所以為了實現(xiàn)帶邊框的文本組件,我就直接繼承了TextView組件,在它的基礎上進行擴充了,代碼如下:
public class BorderTextView extends TextView { /** * 四周是否帶有邊框【true:四周帶有邊框】【false:四周不帶邊框】 */ boolean borders = false; /** * 左邊是否帶有邊框【true:左側帶有邊框】【false:左側不帶邊框】 */ boolean borderLeft = false; /** * 頂部是否帶有邊框【true:頂部帶有邊框】【false:底部不帶邊框】 */ boolean borderTop = false; /** * 右側是否帶有邊框【true:右側帶有邊框】【false:右側不帶邊框】 */ 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); // 是否設置全部邊框,默認為false borders = typedArray.getBoolean( R.styleable.BorderTextView_layout_borders, false); // 是否設置左側邊框,默認為false borderLeft = typedArray.getBoolean( R.styleable.BorderTextView_layout_borderLeft, false); // 是否設置頂部邊框,默認為false borderTop = typedArray.getBoolean( R.styleable.BorderTextView_layout_borderTop, false); // 是否設置右側邊框,默認為false borderRight = typedArray.getBoolean( R.styleable.BorderTextView_layout_borderRight, false); // 是否設置底部邊框,默認為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(); // 設置畫筆顏色 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) { // 畫右側邊框線 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); } } // 設置畫筆顏色歸位 paint.setColor(color); } }
其實給BorderTextView添加邊框也是很簡單,原理就是其draw方法中繪畫出邊框罷,我們都知道每一個View控件在屏幕上顯示出來大致可以歸納為三大步驟,首先調(diào)用View控件的onMesure方法,其次調(diào)用View控件的onLayout方法,再次調(diào)用View控件的onDraw方法,所以我們只需要在draw方法中繪制出邊框就行了,繪制邊框的步驟很簡單,代碼注釋也很詳細,就不再詳細講解了
最后運行一下程序來看一下效果圖吧,呵呵
好了,今天的自定義屬性實現(xiàn)帶邊框的TextView控件就講解完了,謝謝大家的閱讀。
源碼下載:Android UI實現(xiàn)帶下劃線的文本框
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Android自定義TextView實現(xiàn)文字傾斜效果
- Android 讓自定義TextView的drawableLeft與文本一起居中
- 自定義TextView跑馬燈效果可控制啟動/停止/速度/焦點
- android TextView設置中文字體加粗實現(xiàn)方法
- Android TextView設置背景色與邊框的方法詳解
- android實現(xiàn)上下滾動的TextView
- android TextView多行文本(超過3行)使用ellipsize屬性無效問題的解決方法
- android TextView不用ScrollViewe也可以滾動的方法
- Android控件系列之TextView使用介紹
- Android 自定義TextView實現(xiàn)文本內(nèi)容自動調(diào)整字體大小
相關文章
使用SignalR推送服務在Android的實現(xiàn) SignalA
SignalA是老外寫的用于實現(xiàn).net端推送消息至安卓端的實現(xiàn),支持版本為android 2.3或以上2014-07-07詳解Android Material設計中陰影效果的實現(xiàn)方法
這篇文章主要介紹了Android Material設計中陰影效果的實現(xiàn)方法,包括自定義陰影的輪廓和裁剪等,需要的朋友可以參考下2016-04-04Android開發(fā)實現(xiàn)的獲取sdcard大小及內(nèi)存大小工具類
這篇文章主要介紹了Android開發(fā)實現(xiàn)的獲取sdcard大小及內(nèi)存大小工具類,涉及Android針對手機硬件SD卡及內(nèi)存相關操作技巧,需要的朋友可以參考下2017-11-11Android中ScrollView 滑到頭部或尾部可伸縮放大效果
最近做項目遇到這樣的需求S當crollView 滑動到頂部,不能在滑動的時候,圖片可以下拉放大,松開又恢復,滑到底部沒有內(nèi)容的時候,也有伸縮效果,下面通過實例代碼給大家介紹Android ScrollView 滑到頭部或尾部可伸縮放大功能,一起學習吧2017-03-03Android GSYVideoPlayer視頻播放器功能的實現(xiàn)
這篇文章主要介紹了Android GSYVideoPlayer視頻播放器功能的實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03Android實現(xiàn)自動變換大小的ViewPager
ViewPager使用適配器類將數(shù)據(jù)和view的處理分離,ViewPager的適配器叫PagerAdapter,這是一個抽象類,不能實例化,所以它有兩個子類:FragmentPagerAdapter 和 FragmentStatePagerAdapter,這兩個都是處理頁面為Fragment的情況2022-11-11