注:本文部分知識點參考了郭霖的《第一行代碼》(第二版)
一、簡單了解控件和布局的繼承結(jié)構(gòu)
我們所有的控件都是直接或間接繼承自View,所有的布局都是直接或間接繼承自ViewGroup的,如下圖所示:
View是Android中最基本的一種UI組件,它可以在屏幕上繪制一塊矩形區(qū)域,并能相應(yīng)這塊區(qū)域的各種事件,因此,我們使用的各種控件其實就在在View的基礎(chǔ)上又添加了各自特有的功能。而ViewGroup則是一種特殊的View,它可以包含很多子View和子ViewGroup,是一個用于放置控件和布局的容器。
二、引入布局
在這里,我們做一個實例,就是常見的標(biāo)題欄布局的引入。在一個應(yīng)用中,有很多個活動都需要同樣的一個標(biāo)題欄,如果在每個活動的布局中都編寫一遍同樣的標(biāo)題欄代碼,機(jī)會導(dǎo)致大量的代碼重復(fù),也使我們的工作缺乏效率,這個時候我們就可以通過引入布局來解決這個問題。
新建一個布局title.xml(具體步驟為:在res目錄下找到layout文件夾選中——右鍵——New——XML——Layout XML File),確定后出現(xiàn)下圖界面:
第一行的Layout File Name是讓我們輸入布局名稱,這里我們命名為title,第二行的Root Tag是選擇我們的根布局,這里我們用Linearlayout。點擊Finish,布局就創(chuàng)建完成了。
我們在布局里設(shè)置一個Button用于返回,一個TextView用于顯示標(biāo)題,一個Button用于編輯,代碼如下:
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal">? ? <Buttonandroid:id="@+id/title_back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="Back"android:textAllCaps="false"android:layout_margin="5dp"/>? ? <TextViewandroid:id="@+id/title_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:layout_gravity="center"android:gravity="center"android:text="Title Text"android:textSize="24sp"/>? ? <Buttonandroid:id="@+id/title_edit"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="Edit"android:textAllCaps="false"android:layout_margin="5dp"/>LinearLayout>
其中Button的android:layout_margin指的是它在上下左右方向上的偏移距離。
標(biāo)題布局編寫完成了,接下來我們要做的就是在你想要添加標(biāo)題的活動布局中引入標(biāo)題布局。在這里,我在activity_main.xml中引入了標(biāo)題布局,如下:
我們只用了一句include語句就已經(jīng)將標(biāo)題布局引入到了主Activity的布局文件中。還有一件事別忘啦,系統(tǒng)是自帶有標(biāo)題欄的,如果要顯示我們自己加入的標(biāo)題欄,就要做一些處理讓系統(tǒng)自帶標(biāo)題欄隱藏掉。具體代碼如下:
現(xiàn)在我們可以運(yùn)行程序,來看一下效果:
三、創(chuàng)建自定義控件
在第二步中,我們很輕易的就實現(xiàn)了標(biāo)題布局文件的引入,但是我們?nèi)绻胍憫?yīng)標(biāo)題布局文件中的控件,就需要在主Activity中為這些控件單獨編寫一次事件注冊的代碼;如果有多個Activity引入了標(biāo)題布局文件,我們就需要在各個Activity中為控件編寫一次事件注冊代碼;然而,我們發(fā)現(xiàn),標(biāo)題欄中的返回按鈕在各個Activity中的作用都是相同的,即銷毀當(dāng)前Activity,如果我們在每個Activity當(dāng)中都寫一遍銷毀代碼,就顯得冗余和重復(fù),所以這種情況最好是使用自定義控件的方式來解決。
我們新建一個TitleLayout布局,具體操作步驟為:在工程目錄下找到Java文件夾——打開找到你自己的工程包——右鍵——New——JavaClass,如下圖:
在Name中填入類名,這里我們新建的是TitleLayout類,點擊OK,完成創(chuàng)建。
TitleLayout繼承LinearLayout,完成繼承后,你會發(fā)現(xiàn)代碼下面出現(xiàn)了一條紅線,將鼠標(biāo)指針放在有紅線的代碼,點擊Alt+Enter快捷鍵,然后點擊提示的信息“Create constructor matching super”,接下來出現(xiàn)如下界面:
我們選擇創(chuàng)建第二個方法,OK后,創(chuàng)建繼承于LinearLayout類的自定義TitleLayout就完成了。接下來我們將title布局文件放入TitleLayout布局中,代碼如下:
這時,主Activity中就不需要引入title.xml布局文件了,應(yīng)引入TitleLayout布局,引入方式基本上是一樣的,只不過在添加自定義控件的時候,要指明自定義控件的類名、包名,代碼如下:
這個時候運(yùn)行程序,出現(xiàn)的效果和第二步的是一樣的。接下來我們要為標(biāo)題欄中的控件添加自定義事件,修改TitleLayout中的代碼,如下:
首先用findViewById()方法得到按鈕的實例,然后分別調(diào)用setOnClickListener()方法給兩個按鈕注冊點擊事件,當(dāng)點擊返回按鈕是銷毀當(dāng)前活動,當(dāng)點擊編輯按鈕時,彈出一段文本,運(yùn)行一下,效果如下:
這樣的話,每當(dāng)我們在一個布局中引入TitleLayout時,返回按鈕和編輯按鈕的點擊事件就已經(jīng)自動實現(xiàn)好了。
本文的例子和知識點結(jié)論大都引用到郭霖著作《第一行代碼》(第二版),我覺得這本書還是很適合新手閱讀的,例子很簡單,講解的也很清楚,安利一下~~