Android 筆記 - ConstraintLayout 佈局

現在都以這種佈局為主
大概可以完成80%以上的畫面了吧
(原則上不使用  match_parent  而改用  0dp  也就是所謂的 match constraints)

基本用法

先來個xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
>

<TextView
android:id="@+id/tv_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/tv_2"
/>

<TextView
android:id="@+id/tv_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_1"
app:layout_constraintBottom_toBottomOf="parent"
/>

</androidx.constraintlayout.widget.ConstraintLayout>

效果圖如下

在xml開頭的地方,加了下列這行之後

xmlns:app="http://schemas.android.com/apk/res-auto"

才能使用下列這種排列方式

app:layout_constraintStart_toStartOf="parent"

共有以下八種

app:layout_constraintStart_toStartOf=""        << 自己的左邊別人的左邊貼在一起
app:layout_constraintStart_toEndOf=""         << 自己的左邊別人的右邊貼在一起
app:layout_constraintEnd_toEndOf=""         << 自己的右邊別人的貼在一起
app:layout_constraintEnd_toStartOf=""        << 自己的右邊別人的左邊貼在一起
app:layout_constraintTop_toTopOf=""        << 自己的上面別人的上面貼在一起
app:layout_constraintTop_toBottomOf=""        << 自己的上面別人的下面貼在一起
app:layout_constraintBottom_toBottomOf=""      << 自己的下面別人的下面貼在一起
app:layout_constraintBottom_toTopOf=""        << 自己的下面別人的上面貼在一起

雙引號裡面,可以放

"parent"        << 父視窗
"@+id/tv_2"     << 同頁裡定義的其他物件的 id


進階用法 - Guideline

如果要從畫面中間開始對齊可以使用這個方法

基本 xml 如下

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="100dp" />

效果圖如下

可以使用的定位方法如下所列(只能選擇一種)

app:layout_constraintGuide_begin="100dp"        << 從左邊算來 100dp 的距離
app:layout_constraintGuide_end="100dp"        << 從右邊算來 100dp 的距離
app:layout_constraintGuide_percent="0.4"        << 從左邊算來 百分之40 的距離

也可以將垂直改為水平方式
(begin會改從上面算起,end改從底下算起,percent改為從上面算起)

android:orientation="horizontal"


進階用法 - chainStyle

一行有多個物件排列在一起的話,可以使用這個方法,讓它以不同的方式排列

xml 用法如下

app:layout_constraintVertical_chainStyle=""        << 垂直排列方式
app:layout_constraintHorizontal_chainStyle=""      << 水平排列方式

雙引號裡面,可以放以下的 1、2、4

1. "spread"
2. "spread_inside"
3. "weighted"
4. "packed"

相對應的效果圖如下

“3” 則是使用 spread 或 spread_inside 時,將一或多個物件設定為 "match constraints"(0dp) 時,它會自動填滿。當有多個物件都設定為 0dp 時,這些設定為 0dp 的所有物件則是平均分配。
也可以使用 layout_constraintHorizontal_weight 和 layout_constraintVertical_weight 來定義權重

進階用法 - Circle

用角度決定物件位置

app:layout_constraintCircle="@+id/item1"   (相依的物件id)
app:layout_constraintCircleAngle="45"  (0-360,依順時針)
app:layout_constraintCircleRadius="60dp"  (距離)
 

進階用法 - percent

用百分比設定物件大小

android:layout_width="0dp"
app:layout_constraintWidth_percent="0.5"

android:layout_height="0dp"
app:layout_constraintHeight_percent="0.5"

進階用法 - Ratio

物件寬高比例設定

app:layout_constraintDimensionRatio="1.5"
(或 2:1、W,1.5、W,2:1(寬動態,寬比例:高比例)、H,2:1(高動態,寬比例:高比例))

進階用法 - Barrier

把多個物件看做一個物件後,使用的最大邊界

<androidx.constraintlayout.widget.Barrier
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right" (可填入 top, bottom, left, right, start, end)
app:constraint_referenced_ids="item1,item2" /> (填入放其他物件的id, 使用逗號隔開)

進階用法 - Group

把多個物件群組起來,可以一起設定 visibility (在群組內的物件,無法單獨指定 visibility)

<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="item1,item2" /> (填入放其他物件的id, 使用逗號隔開)

進階用法 - constrainSet 

可用此方法動態設定 constraint 的參數,而不需透過xml指定
(或用 ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(0, 0); 設定參數)
------
也可用於兩個類似UI的佈局轉變動畫)(以下是官方說明) (另外也可改用xml的方式定義)
     public class MainActivity extends AppCompatActivity {
         ConstraintSet mConstraintSet1 = new ConstraintSet(); 
         ConstraintSet mConstraintSet2 = new ConstraintSet();
         ConstraintLayout mConstraintLayout;
         boolean mOld = true;

         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             Context context = this;
             mConstraintSet2.clone(context, R.layout.state2);
             setContentView(R.layout.state1);
             mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main);
             mConstraintSet1.clone(mConstraintLayout);
         }

         public void foo(View view) {
             TransitionManager.beginDelayedTransition(mConstraintLayout);
             if (mOld = !mOld) {
                 mConstraintSet1.applyTo(mConstraintLayout);
             }  else {
                 mConstraintSet2.applyTo(mConstraintLayout);
             }
         }
     }

其他

android:layout_width="0dp"
android:layout_width="wrap_content"
app:layout_constrainedWidth="true"  (寬度自適應,可配合guideline使用)
------
android:layout_width="0dp"
app:layout_constraintWidth_default="percent"  (可填入 "percent"(依父視窗的百分比)、"wrap"(依物件本身)、"spread"(放最大))
app:layout_constraintWidth_percent="0.8"
------
app:layout_constraintHorizontal_bias="0.1" (可以調整 View 在約束之間的偏移量)

沒有留言:

張貼留言