本系列持續更新中....php
一個界面老是要由許多的控件來組成的,如何讓這些控件能夠在界面上有條不絮的擺放呢?這就須要佈局來實現了。佈局是一種能夠放置不少控件的容器,可讓這些控件按照必定的規律來排列。java
佈局內便可以放置普通控件也能夠放置佈局,能夠有多層嵌套。關係圖android
接下來介紹 Android 中 4 中經常使用的基本佈局bash
Linerlayout
又稱爲線性佈局,是一種很是經常使用的佈局,這個佈局會將它所包含的全部控件在線性方向上排列。app
既然是線性那麼確定就不止一個方向了,經過 android:orientation
屬性來指定排列的方向。vertical
表明垂直排列,horizontal
是水平排列。ide
代碼:佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"/>
</LinearLayout>
複製代碼
上面是垂直排列,而後咱們把 android:orientation="vertical"
修改成 android:orientation="horizontal"
學習
效果:gradle
注意若是把排列設置爲 vertical
則內部控件的高度就不能設置成 match_parent
由於若是你這樣設置的話,其餘控件就沒有空間了。一樣的若是排列爲 horizontal
的話內部控件的寬度就不能指定爲 match_parent
ui
android:gravity
用於指定文字在本控件中的對齊方式。
android:layout_gravity
用於指定本控件在佈局中的對齊方式。
注意若是排列方向是 horizontal
的話,則 layout_gravity
只有垂直方向上的對齊方式纔會生效,由於此時水平方向上的長度是不固定的,每添加一個控件水平方向上的長度都會改變。一樣道理,排列方向是 vertical
的時候,layout_gravity
只有在水平方向上對齊方式纔會有效。
android:layout_weight
屬性容許我使用比例的方式來指定控件的大小,在屏幕適配方面有很是重要的做用。
RelativeLayout
稱做相對佈局,它是經過相對定位的方式讓控件出如今佈局的任何位置。
重要屬性:
android:layout_alignParentLeft android:layout_alignParentRight android:layout_alignParentTop android:layout_alignParentBottom android:layout_centerInParent
這幾個屬性都是內部控件相對於父控件的排列位置。
一樣也有相對於控件進行定位的 layout_above layout_below layout_toLeftOf layout_toRightOf
alignLeft
表示讓一個控件的左邊和另外一個控件的左邊對齊
alignRight
表示一個控件的右邊和另外一個控件的右邊對齊
alignTop
alignBottom
道理也是同樣
FrameLayout
稱做幀佈局。應用場景較少,全部控件都默認擺放在佈局的左上角。
<?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">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
</FrameLayout>
複製代碼
效果
能夠看到後面添加的 ImageView 被遮擋了。
layout_gravity
屬性在控件中仍是生效的。
前面三種佈局都是在 Android 1.0 版本中就支持了。一直沿用到如今。在 LinearLayout
中支持使用 layout_weight
屬性來實現按照比例來控制控件的大小,其餘兩種佈局就不支持了。爲此 Android 引入了全新的佈局方式來解決此問題-----百分比佈局。在 API 24.1.0 新添加的,不過在 API 26 中就不推薦使用了。
因爲 LinearLayout 自己已經支持按照比例指定控件大小了,所以百分比佈局只是爲了 FrameLayout
和 RelativeLayout
進行了功能擴展,提供了 PercentFrameLayout
和 PercentRelativeLayout
兩個全新的佈局。
因爲百分比佈局是在後來添加的,因此爲了兼容以前版本,Android 團隊將百分比佈局定義在了 support 庫
中(若是你如今使用了 androidx
就沒有這些問題了,這些支持庫都統一放在了 androidx 中)。所以咱們須要先引入一下(若是你使用的是 androidx 就不用引用了)
// 在 app/build.gradle文件中
dependencies{
// 添加
compile 'com.android.support:percent:24.2.1'
}
複製代碼
<?xml version="1.0" encoding="utf-8"?>
<androidx.percentlayout.widget.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:layout_gravity="left"
app:layout_widthPercent = "50%"
app:layout_heightPercent = "50%"
android:layout_height="wrap_content"
android:text="@string/app_name" />
<Button
app:layout_widthPercent = "50%"
app:layout_heightPercent = "50%"
android:layout_gravity="right"/>
<Button
app:layout_widthPercent = "50%"
app:layout_heightPercent = "50%"
android:layout_gravity="left|bottom"/>
<Button
app:layout_widthPercent = "50%"
app:layout_heightPercent = "50%"
android:layout_gravity="right|bottom"/>
</androidx.percentlayout.widget.PercentFrameLayout>
複製代碼
效果圖:
因爲 PercentFrameLayout 不是系統 SDK 中的,所以有些屬性還要用 app
這種命名空間。咱們之因此可以使用 app
前綴的屬性就是由於咱們在開頭加入了定義 app
的命名空間,固然咱們一直使用 android
前綴的屬性也是一樣的道理,只不過是系統幫咱們自動添加了。
使用百分比佈局主要就是這兩個屬性 app:widthPercent 和 app:heightPercent
使用的時候 Android Studio 的佈局編輯頁面能夠會有紅色下劃線提醒,這是由於咱們沒有使用 android:layout_width 和 android:layout_height
。不過這不影響運行程序。
PercentRelativeLayout 的用法也是相似,繼承了 RelativeLayout 的全部屬性。
這樣幾種經常使用的佈局就講完了,還有 AbsoluteLayout
TableLayout
等佈局不常使用就不講解了。
上一節咱們學習了 Android 中的一些經常使用的控件和佈局的用法。這裏咱們來看一下他們的關係圖
能夠看到說有的控件都是直接或者間接繼承 View
,全部的佈局都是直接或者間接繼承 ViewGroup
。
View 是 Android 中最基本的一種 UI 組件,它能夠在屏幕上繪製一塊矩形區域,而且可以響應這塊區域的各類事件,所以,咱們使用的各類控件其實就是在 View 的基礎的又添加了一些特有的功能。而 ViewGroup 是一種特殊的 View ,它能夠包含不少子 View 和 子 ViewGroup,是一個用於放置控件和佈局的容器。
那麼當系統給我提供的控件不能知足咱們的須要的時候,咱們也能夠本身建立符合咱們本身需求的控件。
咱們知道如今的應用程序幾乎在界面頂部都有一個標題欄,雖然 Android 系統已經給咱們提供了,可是這裏咱們不用它,咱們本身建立一個。
咱們本身建立一個佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:orientation="horizontal">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/title_back" android:background="@color/colorAccent" android:layout_gravity="center" android:text="back" android:textAllCaps="false" android:textColor="#FFFFFF"/>
<TextView android:layout_gravity="center" android:layout_width="0dp" android:layout_weight="1" android:textSize="24sp" android:layout_height="wrap_content" android:text="Text Title" android:id="@+id/title_text" android:gravity="center" />
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:background="@color/colorPrimaryDark" android:text="Edit" android:textAllCaps="false"/>
</LinearLayout>
複製代碼
就這樣這個簡單的標題欄佈局就寫好了,那麼如何使用呢?很簡單,在須要使用的佈局中。
<include layout="@layout/title"/>
複製代碼
就添加上面一句話就把剛剛的佈局引入了。
使用的時候不要忘了隱藏自帶的標題欄
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ui);
ActionBar actionBar = getSupportActionBar();
if (actionBar !=null){
actionBar.hide();
}
initView();
}
複製代碼
引入佈局的技巧確實解決了重複編寫佈局代碼的問題,可是佈局中有一些控件還須要響應事件,這種狀況就須要咱們來自定義控件了。
新建 TitleLayout 繼承自 LinearLayout,讓它做爲咱們自定義標題欄的控件。
public class TitleLayout extends LinearLayout {
public TitleLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.title,this);
Button btBack = findViewById(R.id.title_back);
Button btEdit = findViewById(R.id.bt_edit);
btBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
((Activity)getContext()).finish();
}
});
btEdit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 你本身想作的事情
}
});
}
}
複製代碼
好了這樣一個標題欄自定義控件就完成了。