iOSエンジニアのつぶやき

毎朝8:30に iOS 関連の技術について1つぶやいています。まれに釣りについてつぶやく可能性があります。

知識ゼロからの Kotlin Android アプリリリースへの軌跡 / Day9【Codelabs 2-3編】

学ぶこと

  • アプリで ConstraintLayout を使用して View を配置する方法
  • TextView の背景色を変更する方法
  • ベースライン制約を使用して View を text の位置に合わせる方法
  • View のグループから horizontal チェーンと vertical チェーンを作成する方法

すること

  • ColorMyViewsアプリを作成します。
  • TextView にクリックハンドラーを追加して、ユーザがタップした時に View の色を変更します。
  • 異なるフォントサイズの TextView を追加し、ベースライン制約を使用してそれらを整列させます。
  • 3つのボタンのチェーンを追加し、チェーンをレイアウトの下部に制限します。

アプリの概要

絵は静的ですが、アプリはインタラクティブになります。アプリは、タップすると色が変わるクリック可能な TextView と、constraintLayout の button view で構成されます。

|||| |---|---|---|

ConstraintLayout

ConstraintLayout は、柔軟に子 View の位置とサイズを設定できる ViewGroup です。ConstraintLayout を使用すると、フラットな View 階層(ネストされた ViewGroup なし)で大きく複雑なレイアウトを作成できます。ConstraintLayout を構築するには、レイアウトエディターを使用して制約を追加し、View をドラッグアンドドロップします。XML を編集する必要はありません。

Note: ConstraintLayout は、サポートライブラリとして利用できます。これは API Level 9以降で利用できます。

Constraints

constraint は、2つの UI要素間の接続または配置です。各制約は、1つの View を別の View、親レイアウト、または非表示のガイドラインに接続または位置合わせします。ConstraintLayout で、少なくとも1つの horizontal 制約と vertical 制約を定義して View を配置します。

① Horizontal constraint: B は A の右側にとどまるように制約されます。(本来は、B はこの水平方向の制約に加えて少なくとも1つの vertical constraint が必要になります。)

② Vertical constraint: C は A の下にとどまるように制約されます。(本来は、C はこの垂直方向の制約に加えて少なくとも1つの水平方向の制約が必要になります。)

ColorMyViews プロジェクトを作成する

  1. Android Studio を開き、次のパラメータを使用して新しいプロジェクトを作成します。
Attribute Value
Template Empty Activity
Application Name ColorMyViews
Company Name android com.android.example.colormyviews(or your own domain)
Language Kotlin
Minimum API level API 19: Android 4.4(KitKat)
This project will support instant apps (leavi this box cleared)
Use AndroidX artifacts Select this box

Empty Activity テンプレートは、MainActivity.kt ファイルに単一の Activity を作成します。テンプレートは、activity_main.xml というレイアウトファイルも作成します。レイアウトは、root view group として ConstraintLayout を使用し、レイアウトのコンテンツとして単一の TextView を使用します。

  1. Android Studio が Gradle ビルドを完了するまで待ちます。エラーが発生した場合は、Build > Rebuild Project を選択します。

  2. アプリを実行し、ビルドが完了するまで数秒待ちます。真ん中に "Hello world" が表示されます。

Layout Editor を使用して ConstraintLayout を構築する

このタスクでは、Android Studio Layout Editor を使用して、アプリの ConstraintLayout を作成します。

Android Studio の作業領域を設定する

  1. activity_main.xml ファイルを開き、Desing タブに切り替えます。

  2. 制約を手動で追加するため、自動接続をオフにする必要があります。Toolbar で、以下に示す Turn Off/On Autoconnect ボタンを見つけます。(ツールバーが表示されない場合は、レイアウトエディターのデザインエディター領域) autoconnect がオフになっていることを確認します。

Autoconnect オン Autoconnect オフ(このコードラボではこの設定を適用します。)
  1. ツールバーを使用して、デフォルトのマージンを 16dp に設定します。(デフォルトは 8dp)

デフォルトのマージンを 16dp に設定すると、指定したマージンで新しい制約が作成されるため、制約を追加するたびにマージンを追加する必要はありません。

  1. Hello World text view をダブルクリックして、Attributes ペインを開きます。

View inspector

下のスクリーンショットに示す view inspector は、Attributes ペインの一部です。view inspector には、制約、制約タイプ、制約バイアス、view margin などのレイアウト attributes のコントロールが含まれています。

Tip: view inspector は、ConstraintLayout 内にある view でのみ使用できます。

Constraint bias

constraint bias は、水平および垂直軸に沿って view 要素を配置します。デフォルトでは、view は50%のバイアスで2つの制約の中央に配置されます。

バイアスを調整するには、view inspector のバイアススライダーをドラッグすると、軸に沿った View の位置が変更されます。

Hello World TextView にマージンを追加する

  1. view inspector では、TextView の toprightleftbottom のマージンが 0 であることに注目してください。

  2. leftrighttop については、View inspector のドロップダウンメニューから 16dp を選択します。たとえば、次のスクリーンショットでは、layout_marginEnd(layout_marginRight) を追加しています。

TextView の制約とマージンを調整する

View inspector では、正方形の内側の矢印が制約のタイプを表します。

Wrap Content Fixed Match Constraints
View は、そのコンテンツを含めるために必要なだけ拡張されます。 矢印の横にあるテキストボックスで、view margin として寸法を指定できます。 View は、View 自体のマージンを考慮した後、両側の制約を満たすために可能な限り拡大します。この制約は、レイアウトを様々な画面サイズや向きに適応させることができるため、非常に柔軟です。View を制約に一致させることで作成するアプリのレイアウトが少なくて済みます。
  1. View inspector で、左右の制約を Match Constraint に変更します。(矢印をクリックして切り替える)

  1. view inspector で、下部の制約のドットをクリックして、下部の制約を削除します。

  2. Code タブに切り替えます。layout_marginStar の dimension resource を抽出し、リソース名を margin_wide に設定します。

  1. topend に同じ dimension resource を設定します。
android:layout_marginStart="@dimen/margin_wide"
android:layout_marginTop="@dimen/margin_wide"
android:layout_marginEnd="@dimen/margin_wide"

TextView のスタイル

フォントを追加

  1. Attribute ペインで、fontFamily を検索し、その横にあるドロップダウン矢印を選択します。More Font までスクロールして選択します。Resources ダイアログが開きます。

  1. Resource ダイアログで、roboto を検索します。

  2. Roboto を選択して、Preview リストで、Reguluar を選択します。

  3. Add font to project ラジオボタンを選択します。

  4. OK をクリックします。

これにより、roboto.ttf フォントファイルを含む res/font フォルダーが追加されます。また、@font/roboto attribute が TextView に設定されます。

スタイルを追加

  1. res/value/dimens.xml を開き、フォントサイズに次の dimension resource を追加します。
<dimen name="box_text_size">24sp</dimen>
  1. res/values/styles.xml を開いて、TextView に使用する次のスタイルを追加します。
<style name="whiteBox">
   <item name="android:background">@android:color/holo_green_light</item>
   <item name="android:textAlignment">center</item>
   <item name="android:textSize">@dimen/box_text_size</item>
   <item name="android:textStyle">bold</item>
   <item name="android:textColor">@android:color/white</item>
   <item name="android:fontFamily">@font/roboto</item>
</style>

このスタイルでは、背景色とテキスト色がデフォルトの Android カラーリソースに設定されています。フォントは Roboto に設定されています。テキストは中央揃えで太字になり、テキストサイズは box_text_size に設定されます。

TextView の文字列リソースを追加します

  1. Attribute ペインで、text attribute を見つけます。(レンチアイコンのないものが必要です。)

  2. text attribute をクリックして Resources ダイアログを開きます。

  3. Resource ダイアログで、Add new resource > New string Value を選択します。リソース名を box_one に設定し、値を Box One に設定します。

  4. OK をクリックします。

TextView の attribute の設定を終了する

  1. Attributes ペインで、TextView の IDbox_one_text に設定します。

  2. style@style/whiteBox に設定します。

  3. コードをクリーンアップするには、Text タブに切り替えて、android:fontFamily="@font/roboto" attributes を削除します。これは、このフォントが whiteBox スタイルに存在するためです。

  4. Design タブに切り替えます。デザインエディターの上部にある Device for preview(D) ボタンをクリックします。異なる画面構成のデバイスタイプのリストが表示されます。デフォルトのデバイスPixel です。

  1. リストから様々なデバイスを選択し、TextView が様々な画面構成にどのように適合するかを確認します。

  2. アプリを実行します。"Box One" というテキストが付いたスタイル付きの緑色の TextView が表示されます。

2つめの TextView を追加して制約を追加する

このタスクでは、box_one_text の下に別の TextView を追加します。新しい TextView を box_one_text とレイアウトの親要素に制約します。

新しい TextView を追加する

  1. activity_main.xml ファイルを開き、Design タブに切り替えます。

  2. 以下に示すように、Palette ペインから TextView をデザインエディターに直接ドラッグします。TextView を box_one_text の下に配置し、left margin を揃えます。

  3. デザインエディタで、新しい TextView をクリックし、TextView の上部にあるドットを上にポインタを置きます。以下に示すこのドットは、constraint handle と呼ばれます。

constraint handle の上にポインターを置くと、ハンドルが緑色に点滅します。

新しい TextView に制約を追加する

新しい TextView の上部を Box One TextView の下部に接続する制約を作成します。

  1. 新しい TextView の上部の constraint handle の上にポインタを置きます。

  2. view の上部の constraint handle をクリックし、上にドラッグします。constraint line が表示されます。以下に示すように、constraint line を Box One TextView の下部に接続します。

クリックを離すと、制約が作成され、新しい TextView が Box One の下部から16dp以内にジャンプします。(新しい TextView の上部マージンは16dpです。これは、前に設定したデフォルトだからです。)

次に左の制約を追加します:

  1. 新しい View の左側にある constraint handle をクリックします。

  2. Constraint line をレイアウトの左端にドラッグします。

Tip: view inspector を使用して制約を作成することもできます。例えば、新しいテキストボックスに左の制約を作成するには:

  1. preview で、新しいテキストボックスをクリックして選択します。

  2. view inspector で、以下に示すように、ボックスの左側にある + アイコンをクリックします。

この方法で制約を作成すると、制約は親または親に近い View にアタッチされます。

新しい TextView の attributes を設定する

  1. res/values/strings.xml を開きます。次のコードで新しい文字列リソースを追加します。
<string name="box_two">Box Two</string>
  1. activity_main.xml を開き、Code タブに切り替えます。Attributes ペインを使用して、新しい TextView に次の属性を設定します。
Attribute value
id box_two_text
layout_height 130dp
layout_width 130dp
style @style/whiteBox
text @string/box_two

この場合、TextView の高さと幅に固定サイズを割り当てています。View が常に全てのデバイスとレイアウトで固定サイズになる必要がある場合にのみ、高さと幅に固定サイズを割り当てます。

重要: 実際のアプリを開発する時は、可能な限り、UI要素の高さと幅に柔軟な制約を使用してください。例えば、match_constraint または wrap_content を使用します。アプリにある固定サイズの UI要素が多いほど、様々な画面構成に対するレイアウトの適応性が低くなります。

  1. アプリを実行します。次のスクリーンショットのように、2つの緑色の TextView が上下に表示されます。

TextView のチェーンを作成する

このタスクでは、3つの TextView を追加します。TextView は互いに垂直方向に整列され、Box Two の TextView と水平方向に整列されます。View はチェーンとなります。

Chains

chain は、双方向の制約で相互にリンクされている View のグループです。Chain 内の View は、垂直または水平に配置できます。例えば、次の図は、互いに拘束されている2つの View を示しています。これにより、horizontal chain が作成されます。

Head of the chain

chain の最初の view は、head of the chain と呼ばれます。チェーンの先頭に設定される attributes は、チェーン内の全ての View を制御、配置、および分散します。水平チェーンの場合、ヘッドは左端の View です。垂直チェーンの場合、ヘッドは一番上の View です。以下の2つの図のそれぞれで、"A" はチェーンの先頭です。

||| |---|---|

Chain styles

Chain Styles は、チェーン View を広げて配置する方法を定義します。Chain Style attirbutes を割り当てたり、重みを追加したり、View にバイアスを設定したりして、チェーンのスタイルを設定します。

3つのチェーンスタイルがあります:

  • Spread: これはデフォルトのスタイルです。マージンが考慮された後、View は使用可能なスペースに均等に分散されます。

  • Spread inside: 最初と最後の View は、チェーンの両端の親にアタッチされます。残りの View は、使用可能なスペースに均等に広がっています。

  • Packed: マージンが考慮された後、View は一緒にパックされます。次に、チェーンヘッドのバイアスを変更して、チェーン全体の位置を調整できます。
Packed chain Packed chain with bias
  • Weighted: View は、layout_constraintVertical_weight attribute または layout_constrainVertical_weight 属性に設定された値に基づいて、全てのスペースを埋めるようにサイズ変更されます。例えば、A、B、C、の3つの View を含むチェーンを想像してください。View A は1のウェイトを使用します。View B と C はそれぞれ2のウェイトを使用します。View B と C が閉めるスペースは、View A の2倍です。

チェーンにチェーンスタイルを追加するには、チェーンヘッドの layout.constraintHorizontal_chainStyle または layout_constraintVertical_chainStyle 属性を設定します。このタスクで学習したレイアウトエディターでチェーンスタイルを追加できます。

または、XML コードにチェーンスタイルを追加することもできます。例:

// Horizontal spread chain
app:layout_constraintHorizontal_chainStyle="spread"

// Vertical spread inside chain
app:layout_constraintVertical_chainStyle="spread_inside"

// Horizontal packed chain
app:layout_constraintHorizontal_chainStyle="packed"

3つの TextView を追加して垂直チェーンを作成する

  1. activity_main.xml ファイルを開き、Design タブに切り替えます。3つの TextView を Palette ペインからデザインエディターにドラッグします。以下に示すように、3つの新しい TextView すべてを Box Two TextView の右側に配置します。

  1. string.xml ファイルで、新しい text view の名前に次に文字列リソースを追加します。
<string name="box_three">Box Three</string>
<string name="box_four">Box Four</string>
<string name="box_five">Box Five</string>
  1. 新しい TextView に次の attributes を設定します:
Attribute Top text view Middle text view Bottom text view
ID box_three_text box_four_text box_five_text
text @string/box_three @string/box_four @string/bpx_five
style @style/whiteBox @style/whiteBox @style/whiteBox

Component Tree に、不足している制約に関数エラーが表示されます。これらのエラーは後で修正します。

チェーンを作成し、Box Two の高さに制限する

  1. 3つの TextView をすべて選択して右クリックし、Chains > Create Vertical Chain を選択します。

これにより、Box One からレイアウトの最後まで伸びる垂直チェーンが作成されます。

  1. Box Three の上部から Box Two の上部に伸びる制約を追加します。これにより、既存の Top Constraint が削除され、新しい Constraint に置き換えられます。制約を明示的に削除する必要はありません。

  1. Box Five の下部から Box Two の下部に制約を追加します。

3つの TextView が Box Two の上部と下部に拘束されていることを確認します。

左右の制約を追加する

  1. Box Three の左側を Box Two の右側に拘束します。Box FourBox Five について繰り返し、それぞれの左側を Box Two の右側に制限します。

  1. 3つの TextView のそれぞれの右側をレイアウトの右側に制限します。

  1. 3つの TextView のそれぞれについては、layout_width attribute を 0dp に変更します。これは、制約タイプを Match Constraint に変更することと同じです。

マージンを追加

Attributes ペインを使用して、3つの TextView に Layout_margin attribute を設定し、それらの間にスペースを追加します。

  1. Box Three では、Start と End マージンに @dimen/margin_wide を使用します。他のマージンを削除します。

  2. Box Four の場合、StartEndTopBottom のマージンを @dimen/margin_wide に変更し、他のマージンを削除します。

  3. Box Five では、StarEnd@dimen/margin_wide を適用し、他は削除します。

  4. アプリの TextView がデバイス構成の変更にどのように適応するかを確認するには、Orientation for Preview(O) を変更します。Device アイコンをクリックして、Landscape を選択します。

  1. アプリを実行します。5つのスタイル付き TextView が表示されます。広い画面での制約の動作を確認するには、Nexus 10 などのより大きなデバイスまたは エミュレータでアプリを実行してみてください。

||| |---|---|

TextView のクリックハンドラーを追加する

このタスクでは、ColorMyViews アプリをもう少しカラフルにします。まず、全ての TextView の色を白に変更します。次に、ユーザがタップした時に View の色とレイアウトの背景色を変更するクリックハンドラーを追加します。

  1. style.xml ファイルの WhiteBox style 内で、背景色を白に変更します。TextView は白のフォントで始まり、ユーザがタップすると色が変わります。
<item name="android:background">@android:color/white</item>
  1. MainActivity.ktonCreate() 関数の後に、makeColored() という関数を追加します。関数のパラメーターとして View を使用します。この View は色が変化する View です。
private fun makeColored(view: View) {
}

全ての View には resourceID があります。resourceID は、Layout File で id attribute に割り当てられた値です。色を設定するために、コードは View のリソースID の when ステート麺とを使用して切り替えます。 クリックアクションが同じ場合、多くの View で1つのクリックハンドラー関数を使用するのは一般的なパターンです。

  1. makedColored() 関数を実装します。when ブロックを追加して、View の Resource ID を確認します。各 View の ID で setBackgroundColor) 関数を呼び出し、Color クラスの constraints を使用して View の背景色を変更します。

コードのインデントを修正するには、Code > Reformat code を選択します。

private fun makeColored(view: View) {
   when (view.id) {
      
       // Boxes using Color class colors for the background
       R.id.box_one_text -> view.setBackgroundColor(Color.DKGRAY)
       R.id.box_two_text -> view.setBackgroundColor(Color.GRAY)
       R.id.box_three_text -> view.setBackgroundColor(Color.BLUE)
       R.id.box_four_text -> view.setBackgroundColor(Color.MAGENTA)
       R.id.box_five_text -> view.setBackgroundColor(Color.BLUE) 
   }
}
  1. 追加したコードを実行するには、android.graphics.Color ライブラリが必要です。Android Studio がこのライブラリを自動的にインポートしていない場合は、import ステートメントを使用して、MainActivity クラスの定義の前にライブラリを追加します。

  2. ユーザが背景をタップした場合、背景色を薄い灰色に変更します。明るい背景は、View の輪郭を明らかにし、次にタップする場所についてのヒントをユーザに提供します。

id がどの View とも一致しない場合は、ユーザが背景をタップしたことが分かります。when ステートメントの最後に、else ステートメントを追加します。else 内で背景色を明るい灰色に設定します。

else -> view.setBackgroundColor(Color.LTGRAY)
  1. activity_main.xml で、ルートの ConstraintLayout に id を追加します。Android システムでは、色を変更するために識別子が必要です。
android:id="@+id/constraint_layout"
  1. MainActivity.kt で、setListeners() という関数を追加して、各 View にクリックリスナー関数 maikeColored() を設定します。findViewById を使用して、各 TextView とルートレイアウトの参照を取得します。各参照を変数に割り当てます。
private fun setListeners() {

   val boxOneText = findViewById<TextView>(R.id.box_one_text)
   val boxTwoText = findViewById<TextView>(R.id.box_two_text)
   val boxThreeText = findViewById<TextView>(R.id.box_three_text)
   val boxFourText = findViewById<TextView>(R.id.box_four_text)
   val boxFiveText = findViewById<TextView>(R.id.box_five_text)

   val rootConstraintLayout = findViewById<View>(R.id.constraint_layout)
}

このコードを実行するには、android.widget.TextView ライブラリが必要です。Android Studio がこのライブラリを自動的にインポートしない場合は、import ステートメントを使用して、MainActivity クラス定義の前にライブラリを追加します。

  1. setListeners() 関数の最後で、View のリストを定義します。リストに clickableViews という名前を付け、全ての View インスタンスをリストに追加します。
fun setListeners() {
...
   val clickableViews: List<View> =
       listOf(boxOneText, boxTwoText, boxThreeText,
              boxFourText, boxFiveText, rootConstraintLayout)
  }
  1. setListeners() 関数の最後で、各 View のリスナーを設定します。for ループと setOnClickLister 関数を使用します。
   for (item in clickableViews) {
       item.setOnClickListener { makeColored(it) } }
  1. MainActivity.ktonCreate() 関数の最後で、setListeners() を呼び出します。
override fun onCreate(savedInstanceState: Bundle?) {
...
   setListeners()
}
  1. アプリを実行します。最初は空白の画面が表示されます。画面をタップすると、ボックスと背景色が表示されます。

||| |---|---|

ベースライン制約を追加する

Baseline constraint

ベースライン制約は、View のテキストのベースラインを別の View のテキストのベースラインに揃えます。特にフォントサイズが異なる場合は、テキストを含む View の整列が難しい場合があります。Baseline Constraint は調整作業を代行します。

View 上にポインターを置くと View の下に表示される Edit Baseline アイコンを使用して、レイアウトエディターで Baseline constraint を作成できます。ベースライン制約の同等の XML コードには、ConstraintLayout attribute、layout_constraintBaseline_toBaselineOf があります。

Baseline Constraint のサンプル XML コード:

<Button
   android:id="@+id/buttonB"
   ...   
   android:text="B"
   app:layout_constraintBaseline_toBaselineOf="@+id/buttonA" />

このタスクでは、アプリの使用方法をユーザに伝える指示を追加します。2つの TextView を作成します。1つはラベル用で、もう1つは指示情報用です。TextView には異なるフォントサイズがあり、ベースラインに揃えます。

ラベルの TextView を追加する

  1. activity_main.xml を開き、Palette ペインからデザインエディターにテキストビューをドラッグします。Box Two の下に TextView を配置します。この TextView は、指示にラベルを付けるテキスト保持します。

  1. string.xml で、ラベル TextView の文字列リソースを作成します。
<string name="how_to_play">How to play:</string>
  1. Attribute ペインを使用して、新しく追加されたラベル TextView に次の attribute を設定します。
Attribute Value
ID label_text
fontFamily roboto
text @string/how_to_play
textSize 24sp
textStyle B (bold)
  1. ツールバーDefault Margins アイコンを使用して、デフォルトのマージンを 16dp に設定します。

  2. label_text View の左側をレイアウトの親要素に制限します。

  1. activity_main.xml ファイルで、レイアウトエディターは、16dp のハードコードされた値で layout_marginStart attribute を追加します。@dimen/margin_wide に置き換えます。XML コードは次のようになります。
<TextView
   android:id="@+id/label_text"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginStart="@dimen/margin_wide"
   android:fontFamily="@font/roboto"
   android:text="@string/how_to_play"
   android:textSize="24sp"
   android:textStyle="bold"
   app:layout_constraintStart_toStartOf="parent"
   tools:layout_editor_absoluteY="287dp"/> <!--Designtime attribute-->

Design-time attributes

Design-time attribute は、実行時ではなく、レイアウト設計時にのみ使用および適用されます。アプリを実行すると、design-time attribute は無視されます。

Design-time の attributes には、上記の生成されたコードスニペットでは、例えば tools namespace、tools:layout_editor_absoluteY などのように、ツールの namespace が前に付けられます。垂直方向の制約をまだ追加していないため、このコード行が追加されています。

ConstraintLayout の全ての View は、水平方向および垂直方向に制約する必要があります。そうしないと、アプリを実行した時に View が親の端にジャンプします。これが、View が水平方向に拘束されていない場合にレイアウトエディターが tools:layout_editor_absokuteX を追加する理由です。レアアウトエディターは、design-time の View の位置を維持するために、design-time attribute にレイアウト内の View の現在の一の値を提供します。Android Studio は制約を作成した後にそれらを削除するため、これらのツール Attribute を無視しても安全です。

design-time attribute を使用して、サンプル preview データをレイアウトエディター内から TextView または ImageView に追加することもできます。

Info text の TextView を追加する

  1. 別の TextView を Palette ペインからデザインエディターにドラッグします。いかに示すように、label_text 右下に view を配置します。この新しい TextView は、ユーザに表示されるヘルプ情報用です。新しい View が labe_text view から垂直方向にオフセットされていることを確認してください。これにより、ベースライン制約を作成した時に何が起こるかを確認できます。

  1. string.xml で、新しい TextView の文字列リソースを作成します。
<string name="tap_the_boxes_and_buttons">Tap the screen and buttons.</string>
  1. Attributes ペインを使用して、次の attributes を TextView に設定します。
Attribute Value
ID info_text
layout_width 0dp
fontFamily roboto
text @string/tap_the_boxes_and_buttons
  1. info_text の右側を親要素の右端に制限します。info_text の左側を labe_text の右端に制約します。

2つの TextView のベースラインを揃える

  1. label_text をクリックします。Edit Baseline アイコンをクリックします。

  2. 以下のように、ポインタをベースラインに置きます。

  1. ベースラインをクリックしてドラッグします。ベースラインを info text view のベースラインに接続します。

2つの TextView に vertical Constraints を追加する

垂直方向の制約がない場合、View は実行時に画面の最上部に移動します。垂直方向の制約を追加すると、アプリを実行する時に2つの TextView が所定の位置に保持されます。

  1. info_text の下部をレイアウトの下部に制限します。

  2. info_text の上部を box_two_text の下部に接続します。

  1. view inspector で、info_text view の垂直バイアスを 0 に変更します。これにより、TextView が上部の制約された View である box_two に近くなります。

  2. 生成されたXMLコードは次のようになります。

<TextView
   android:id="@+id/label_text"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginStart="@dimen/margin_wide"
   android:text="@string/how_to_play"
   android:textSize="24sp"
   android:textStyle="bold"
   app:layout_constraintBaseline_toBaselineOf="@+id/info_text"
   app:layout_constraintStart_toStartOf="parent" />

<TextView
   android:id="@+id/info_text"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:layout_marginStart="@dimen/margin_wide"
   android:layout_marginTop="@dimen/margin_wide"
   android:layout_marginEnd="@dimen/margin_wide"
   android:layout_marginBottom="@dimen/margin_wide"
   android:text="@string/tap_the_boxes_and_buttons"
   app:layout_constraintBottom_toBottomOf="parent"
   app:layout_constraintEnd_toEndOf="parent"
   app:layout_constraintHorizontal_bias="0.0"
   app:layout_constraintStart_toEndOf="@+id/label_text"
   app:layout_constraintTop_toBottomOf="@+id/box_two_text"
   app:layout_constraintVertical_bias="0.0" />
  1. アプリを実行すると下記のようになります。

ボタンの Chain を追加する

このタスクでは、3つの Button を追加し、それらを連結します。

3つのボタンを追加する

  1. activity_main.xml ファイルを開きます。3つのボタンを Palette ペインからレイアウトの下部にドラッグします。

  1. string.xml ファイルで、各ボタンの文字列リソースを追加します。
<string name="button_red">RED</string>
<string name="button_yellow">YELLOW</string>
<string name="button_green">GREEN</string>
  1. attributes を設定します。
Attribute left button Middle button Right button
ID red_button yellow_button green_button
text @string/button_red @string/button_yellow @string/button_green
  1. ボタンのラベルを互いに垂直に揃えます。これを行うにはred_buttongreen_buttonのベースラインをyellow_button のベースラインに制限します。

水平チェーンを作成して拘束します

  1. デザインエディターまたは、ComponentTree で3つのButton を選択して右クリックしてます。Chains > Create Horizontal chain をします。

  1. yellow_button16dp の左右のマージンを追加します。

  1. view inspector を使用して、red_button の左マージンを 16dp に設定します。green_button の右マージンを 16dp に設定します。

  2. yellow_button の上部を info_text の下部に制限します。

  3. yellow_button の下部をレイアウトの下部に設定します。

  1. yellow_button の 垂直バイアスを100に変更して、ボタンをレイアウトの下部にドロップダウンします。

  2. 様々なデバイスと向きでレイアウトをテストします。レイアウトは全てのデバイスと方向で機能するとは限りませんが、ほとんどのデバイスで機能するはずです。

生成された Button の XML ファイルは次のようになります。

<Button
   android:id="@+id/red_button"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginStart="@dimen/margin_wide"
   android:text="@string/button_red"
   android:visibility="visible"
   app:layout_constraintBaseline_toBaselineOf="@+id/yellow_button"
   app:layout_constraintEnd_toStartOf="@+id/yellow_button"
   app:layout_constraintHorizontal_bias="0.5"
   app:layout_constraintStart_toStartOf="parent" />

<Button
   android:id="@+id/yellow_button"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginStart="@dimen/margin_wide"
   android:layout_marginTop="@dimen/margin_wide"
   android:layout_marginBottom="@dimen/margin_wide"
   android:text="@string/button_yellow"
   android:visibility="visible"
   app:layout_constraintBottom_toBottomOf="parent"
   app:layout_constraintEnd_toStartOf="@+id/green_button"
   app:layout_constraintHorizontal_bias="0.5"
   app:layout_constraintStart_toEndOf="@+id/red_button"
   app:layout_constraintTop_toBottomOf="@+id/info_text"
   app:layout_constraintVertical_bias="1.0" />

<Button
   android:id="@+id/green_button"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginEnd="16dp"
   android:text="@string/button_green"
   app:layout_constraintBaseline_toBaselineOf="@+id/yellow_button"
   app:layout_constraintEnd_toEndOf="parent"
   app:layout_constraintHorizontal_bias="0.5"
   app:layout_constraintStart_toEndOf="@+id/yellow_button" />

ボタンにクリックハンドラーを追加する

このタスクでは、各 Button にクリックハンドラーを追加します。クリックハンドラーは、TextView の色を変更します。

  1. 以下の色を res/values/colors.xml ファイルに追加します。
<color name="my_green">#12C700</color>
<color name="my_red">#E54304</color>
<color name="my_yellow">#FFC107</color>
  1. MainActivity.kt で、findViewById() を使用して button view の参照を取得します。これを行うには、次のコードを setListeners() クリックハンドラー関数の clickableViews 宣言の上に配置します。

  2. Button の参照を cliclableViews に追加します。

private fun setListeners() {
   ...
   val clickableViews: List<View> =
       listOf(boxOneText, boxTwoText, boxThreeText,
boxFourText, boxFiveText, rootConstraintLayout,
redButton, greenButton, yellowButton
)
   ... 
}
  1. makeColored() 関数内に、ユーザがボタンをタップした時に TextView の色を変更するコードを追加します。次に示すように、else ステートメントの上に新しいコードを追加します。
private fun makeColored(view: View) {
   when (view.id) {

      ...

       // Boxes using custom colors for background
       R.id.red_button -> box_three_text.setBackgroundResource(R.color.my_red)
       R.id.yellow_button -> box_four_text.setBackgroundResource(R.color.my_yellow)
       R.id.green_button -> box_five_text.setBackgroundResource(R.color.my_green)

       else -> view.setBackgroundColor(Color.LTGRAY)
   }
}
  1. アプリを実行します。

まとめ

  • ConstraintLayout は、レイアウトの子 View を柔軟に配置およびサイズ変更できる ViewGroup です。

  • ConstraintLayout では、各 View の位置は、少なくとも1つの水平制約と少なくとも1つの垂直制約を使用して定義されます。

  • constraint は、View を別の UI要素、親レイアウト、または非表示ガイドラインに接続または配置します。

ConstraintLayout を利用する利点:

  • ConstraintLayout は、様々な画面サイズと解像度を持つデバイスに応答させることができます。

  • ConstraintLayout は通常、LinearLayout よりもフラットな View 階層になります。

  • Android Studio のデザインエディターと view inspector は、制約の追加と構成に役立ちます。

Chains:

  • chain は、双方向の制約で相互にリンクされている View のグループです。

  • チェーン内の View は、垂直または水平に配置できます。

Design-time attributes:

  • Design-time は、実行時ではなく、レイアウト設計時にのみ使用および適用されます。アプリを実行すると、デザイン時の属性は無視されます。

  • Design-time tools namespace が前に付きます。例えば tools:layout_editor_absoluteY

Baseline constraints:

  • ベースライン制約は、View のテキストベースラインを、テキストがある別の View のテキストベースラインに揃えます。

  • ベースライン制約は、View のフォントサイズが異なる場合に役立ちます。

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com