本文的合集已經(jīng)編著成書,高級Android開發(fā)強(qiáng)化實戰(zhàn)颜骤,歡迎各位讀友的建議和指導(dǎo)毅待。在京東即可購買:https://item.jd.com/12385680.html
ConstraintLayout, 即約束布局, 在2016年由Google I/O推出. 從支持力度而言, 將成為主流布局樣式, 完全代替其他布局, 減少布局的層級, 優(yōu)化渲染性能. 在新版Android Studio中, ConstraintLayout已替代RelativeLayout, 成為HelloWorld項目的默認(rèn)布局. ConstraintLayout作為非綁定(Unbundled)的支持庫, 命名空間是app:
, 即來源于本地的包命名空間. 最新版本是1.0.1(2017.4.21), 在項目的build.gradle
中聲明.
dependencies {
compile 'com.android.support.constraint:constraint-layout:1.0.1'
}
本文源碼的GitHub下載地址
概念
ConstraintLayout約束布局的含義: 根據(jù)布局中的其他元素或視圖, 確定View在屏幕中的位置, 受到三類約束, 即其他視圖, 父容器(parent), 基準(zhǔn)線(Guideline).
layout_constraint[本源位置]_[目標(biāo)位置]="[目標(biāo)ID]"
例如:
app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
約束當(dāng)前View的底部
至目標(biāo)View的底部
, 目標(biāo)View是constraintLayout. 即, 把當(dāng)前View的底部對齊到constraintLayout的底部.
演示
本例復(fù)用的Activity頁面, 根據(jù)不同的參數(shù)設(shè)置對應(yīng)的標(biāo)題和布局ID.
public class LayoutDisplayActivity extends AppCompatActivity {
private static final String TAG = LayoutDisplayActivity.class.getSimpleName();
static final String EXTRA_LAYOUT_ID = TAG + ".layoutId"; // 布局ID
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(getIntent().getStringExtra(Intent.EXTRA_TITLE));
final int layoutId = getIntent().getIntExtra(EXTRA_LAYOUT_ID, 0);
setContentView(layoutId); // 設(shè)置頁面布局, 復(fù)用布局
}
}
主頁面使用ListView展示多項, 每項對應(yīng)不同的布局頁面.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView list = (ListView) findViewById(R.id.activity_main);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, LIST_ITEMS);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// 復(fù)用顯示布局
Intent intent = new Intent(MainActivity.this, LayoutDisplayActivity.class);
intent.putExtra(Intent.EXTRA_TITLE, LIST_ITEMS[i]); // 標(biāo)題
intent.putExtra(LayoutDisplayActivity.EXTRA_LAYOUT_ID, LAYOUT_IDS[i]); // 布局Id
startActivity(intent);
}
});
}
}
基礎(chǔ)
ConstraintLayout最基本的使用方式, 就是指定約束. 如, 取消按鈕的底部對齊constraintLayout(父容器)
的底部, 左側(cè)對齊父容器的左側(cè). 下一步按鈕的底部對齊父容器的底部, 而左側(cè)對齊取消按鈕的右側(cè), 每個按鈕添加Margin空隙.
父容器可以直接指定ID, 也可以使用
parent
代指.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:id="@+id/constraintLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
android:text="取消"
app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
app:layout_constraintStart_toStartOf="@id/constraintLayout"/>
<Button
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
android:text="下一步"
app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
app:layout_constraintStart_toEndOf="@id/cancel_button"/>
</android.support.constraint.ConstraintLayout>
ConstraintLayout的屬性設(shè)置, 最重要的就是理解屬性的表示含義.
比例
ConstraintLayout除了指定約束, 還支持設(shè)置比例. Center按鈕的全部邊界與constraintLayout(父容器)
邊界對齊, 則為居中. 同時還可以設(shè)置水平與豎直的比例, 如Bias按鈕, 在對齊父容器后, 設(shè)置水平與豎直的比例均為0.25, 表示左側(cè)與右側(cè)比例是1:4, 上部與下部的比例是1:4.
constraintHorizontal_bias
設(shè)置水平比例, constraintVertical_bias
設(shè)置豎直比例.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Center"
app:layout_constraintEnd_toEndOf="@id/constraintLayout"
app:layout_constraintStart_toStartOf="@id/constraintLayout"
app:layout_constraintTop_toTopOf="@+id/constraintLayout"
app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bias"
app:layout_constraintEnd_toEndOf="@id/constraintLayout"
app:layout_constraintStart_toStartOf="@id/constraintLayout"
app:layout_constraintTop_toTopOf="@+id/constraintLayout"
app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
app:layout_constraintHorizontal_bias="0.25"
app:layout_constraintVertical_bias="0.25"/>
</android.support.constraint.ConstraintLayout>
引導(dǎo)線
ConstraintLayout除了與視圖約束以外, 還支持與引導(dǎo)線(Guideline)
約束. 如, 設(shè)置豎直引導(dǎo)線(Guideline)
距離左側(cè)72dp
. 兩個按鈕的左側(cè)都與引導(dǎo)線約束, 上下使用比例方式排列, 一個是0.25, 一個是0.75.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.Guideline
android:id="@+id/guideLine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="72dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Guide Up"
app:layout_constraintStart_toStartOf="@id/guideLine"
app:layout_constraintTop_toTopOf="@+id/constraintLayout"
app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
app:layout_constraintVertical_bias="0.25"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Guide Down"
app:layout_constraintStart_toStartOf="@id/guideLine"
app:layout_constraintTop_toTopOf="@+id/constraintLayout"
app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
app:layout_constraintVertical_bias="0.75"/>
</android.support.constraint.ConstraintLayout>
視圖尺寸
ConstraintLayout也支持自動填充寬高, 把寬高設(shè)置為0dp
會根據(jù)位置自動填充. 如, Large按鈕, 左側(cè)與Small按鈕的左側(cè)對齊, 右側(cè)與constraintLayout(父控件)
的右側(cè)對齊, 寬度設(shè)置為0dp
, 則會填充全部空位.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:id="@+id/constraintLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small"
app:layout_constraintStart_toStartOf="@id/constraintLayout"
app:layout_constraintTop_toTopOf="@id/constraintLayout"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Large"
app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
app:layout_constraintEnd_toEndOf="@id/constraintLayout"
app:layout_constraintStart_toEndOf="@id/small"
app:layout_constraintTop_toTopOf="@id/constraintLayout"/>
</android.support.constraint.ConstraintLayout>
縱橫比
ConstraintLayout支持使用constraintDimensionRatio
設(shè)置寬高的縱橫比, 把寬(layout_width)或者高(layout_height)設(shè)置為0dp, 則根據(jù)另一個屬性值和比例, 計算當(dāng)前屬性值.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:id="@+id/constraintLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="0dp"
android:layout_height="200dp"
android:background="@color/colorAccent"
android:src="@drawable/total_large"
app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
app:layout_constraintLeft_toLeftOf="@+id/constraintLayout"
app:layout_constraintRight_toRightOf="@+id/constraintLayout"
app:layout_constraintTop_toTopOf="@+id/constraintLayout"
app:layout_constraintDimensionRatio="16:9"/>
<ImageView
android:layout_width="0dp"
android:layout_height="200dp"
android:background="@color/colorAccent"
android:contentDescription="@null"
android:src="@drawable/total_large"
app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
app:layout_constraintDimensionRatio="4:3"
app:layout_constraintLeft_toLeftOf="@+id/constraintLayout"
app:layout_constraintRight_toRightOf="@+id/constraintLayout"/>
</android.support.constraint.ConstraintLayout>
鏈樣式
ConstraintLayout同時支持鏈樣式, 這與LinearLayout的layout_weight
屬性非常類似, 通過設(shè)置不同的樣式排列元素.
app:layout_constraintHorizontal_chainStyle
設(shè)置水平鏈.
<TextView
android:id="@+id/property_tv_cst_aries"
style="@style/MemberWidget.Constellation"
android:layout_marginLeft="@dimen/spacing_big"
android:layout_marginTop="@dimen/spacing_medium"
android:onClick="@{listener::onConstellationSelected}"
android:text="白"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/property_tv_cst_taurus"
app:layout_constraintTop_toBottomOf="@id/property_tv_constellation" />
通過不同的鏈?zhǔn)浇M合, 生成復(fù)雜的視圖樣式.
ConstraintLayout的基本使用方式就是這些, 兼顧LinearLayout與RelativeLayout的優(yōu)點(diǎn), 非常適合構(gòu)建復(fù)雜布局, 降低布局的層級, 加快渲染速度.
OK, that's all! Enjoy it!