FrameLayout 應(yīng)該說(shuō)是 Android 常用UI布局里面最簡(jiǎn)單的一種,顧名思義,它的布局方式就是將 View 一幀一幀的疊加到一起,有點(diǎn)類似 Photoshop 里面的圖層的概念。在學(xué)習(xí) FrameLayout 的過(guò)程中,你會(huì)發(fā)現(xiàn)基于它可以設(shè)計(jì)出很多有意思的 Android UI。那么接下來(lái),我們來(lái)一起一探究竟。
1. FrameLayout 的特性
FrameLayout 是最簡(jiǎn)單且最高效的布局形式,不過(guò) FrameLayout 的使用頻率相比其他的 Layout 來(lái)講要更少很多,主要是因?yàn)楹芏鄷r(shí)候它只是作為一個(gè)容器來(lái)顯示單個(gè) View 或者多個(gè) View 重疊的場(chǎng)景。
用過(guò) Photoshop 的朋友對(duì)“圖層”的概念應(yīng)該比較熟悉,我們可以插入很多個(gè)圖層,后添加的圖層會(huì)擋住先添加的圖層,然后針對(duì)每個(gè)圖層我們可以任意的設(shè)置它在整個(gè)圖片中的位置。同樣的,我們可以設(shè)置 FrameLayout 內(nèi)部 View 所處的位置,與 RelativeLayout 相似,可以設(shè)置放置在上下左右,同樣也可以設(shè)置邊距。如果放置了多個(gè) View,那么他們會(huì)按照放置的順序依次疊加,后加入 View 的會(huì)擋住前面加入的 View。
2. FrameLayout 的常用設(shè)置
在第 1 小節(jié)我們提到過(guò),F(xiàn)rameLayout 可以設(shè)置內(nèi)部 View 所在的位置,那么這幾個(gè)屬性和 RelativeLayout 一樣,這里不再重復(fù),主要介紹一下 FrameLayout 特有又常用的兩個(gè)屬性:android:foreground
和android:foregroundGravity
。
2.1 前景圖像
android:foreground: 設(shè)置 FrameLayout 的前景圖像
前景圖像會(huì)置于 FrameLayout 內(nèi)部所有 View 的層級(jí)之上,直接設(shè)置圖片的資源 id 即可,如下:
android:foreground="@drawable/emercy"
2.2 前景位置
android:foregroundGravity: 設(shè)置 FrameLayout 前景圖片的擺放位置,設(shè)置方式與 RelativeLayout 中的 View 一樣,如:
android:foregroundGravity="bottom|right"
3. 通過(guò) XML 完成一個(gè) FrameLayout
我們的 FrameLayout 需要滿足以下要求:
- 一個(gè)圖片,作為 FrameLayout 的前景;
- 一個(gè) Android Logo 圖片資源(ImageView);
- 一個(gè)文本資源,和 Logo 重疊,可以看到后添加的 View 會(huì)擋住前面添加的 View;
- 一個(gè)文本資源,和前景圖片重疊,可以看到前景圖片時(shí)鐘會(huì)在內(nèi)部 View 之上顯示。
完成以上功能的布局代碼比較簡(jiǎn)單:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="@drawable/emercy"
android:foregroundGravity="bottom|right"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@mipmap/ic_launcher" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:background="#4C374A"
android:padding="10dp"
android:text="Welcome to iMooc"
android:textColor="#FFFFFF"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:background="#1E64D8"
android:padding="10dp"
android:text="Emercy Android"
android:textColor="#FFFFFF"
android:textSize="18sp" />
</FrameLayout>
效果如下:
這就是 FrameLayout 的基本用法。
4. FrameLayout 的適用場(chǎng)景
到這里,基本上你已經(jīng)掌握了 FrameLayout 的用法,可能你會(huì)有所疑惑,看起來(lái) FrameLayout 也沒(méi)有什么特別好的地方,似乎完全可以被 RelativeLayout 替代,所以很多人在開(kāi)發(fā)過(guò)程中,往往會(huì)忘記還有這么個(gè) Layout。其實(shí)越是往后學(xué)你越會(huì)發(fā)現(xiàn),F(xiàn)rameLayout 的簡(jiǎn)單不僅僅體現(xiàn)在使用上,更大的優(yōu)勢(shì)是在于其性能。當(dāng)你的屏幕上控件不太多時(shí),比如 Android 的桌面 Widget,或者 Home 應(yīng)用,大多都是直接采用 FrameLayout 完成的布局。
事實(shí)上,還有一處是 FrameLayout 用的最多的地方,也是一個(gè)非常隱蔽的地方。如果我們打開(kāi) Hierarchy Viewer 或者類似的 View 分析工具,我們可以看到Android的每一個(gè)頁(yè)面都是在一個(gè) FrameLayout 中完成的布局,也就是無(wú)論你定義的布局有多復(fù)雜,最終都會(huì)被放到一個(gè) FrameLayout 當(dāng)中顯示,這也體現(xiàn)了 FrameLayout 的強(qiáng)大,在今后的學(xué)習(xí)工作中,希望大家一定不要忽視了 FrameLayout,在此為大家埋下一個(gè)伏筆。
5. 小結(jié)
這里需要再次強(qiáng)調(diào):FrameLayout 是最簡(jiǎn)單,最高效的布局方式。它的布局方式很容易理解,我們通過(guò)它可以將內(nèi)部的 View 防止到任意的方位,如果內(nèi)部有多個(gè) View,那么按照防止順序,后加入的View會(huì)擋住前面加入的 View。