AndroidでFlexboxLayoutを使ってViewを並べる
FlexboxLayoutなるものが出たというのをチラッと見たので、どんなものなのか試してみました。
FlexboxLayoutは、CSS Flexible Box Layout Module をAndroidに持ち込んだものらしい。
しかしまだバージョンが0.1.2(昨日は0.1.1だった)ということで、まだまだこれからいろいろ変わっていきそうです。が、とりあえず試してみます。
FlexboxLayoutとはなんぞやということについては、W3Cの方を読んだ方がいいかもしれません。
簡単にいうと、Viewを縦方向あるいは横方向に並べつつ、View同士の間隔や高さ、幅を柔軟に伸縮させることができるレイアウトという感じです。
まぁ、実際に動きを見てみましょう。
準備
まずは使うための準備。このあたりはGithubのREADMEの通りにやれば問題ないです。
例によってbuild.gradle(app)を以下のように編集します。
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "techium.com.webviewsample" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.google.android:flexbox:0.2.1' // 追加 }
レイアウトファイルを作成
FlexboxLayoutを使ってレイアウトファイルを作成します。
以下のようなレイアウトを作成してみました。
<?xml version="1.0" encoding="utf-8"?> <com.google.android.flexbox.FlexboxLayout 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:id="@+id/flexbox_layout" app:flexDirection="row" // 8行目 app:flexWrap="nowrap" // 9行目 app:alignItems="flex_start" // 10行目 app:justifyContent="center"> // 11行目 <TextView android:text="Hello World!1" android:layout_width="80dp" android:layout_height="80dp" android:background="#0000FF"/> <TextView android:text="Hello World!2" android:layout_width="80dp" android:layout_height="80dp" android:background="#FFFF00"/> <TextView android:text="Hello World!3" android:layout_width="80dp" android:layout_height="80dp" android:background="#FF0000"/> <TextView android:text="Hello World!4" android:layout_width="80dp" android:layout_height="80dp" android:background="#FF9900"/> <TextView android:text="Hello World!5" android:layout_width="80dp" android:layout_height="80dp" android:background="#FF0099"/> </com.google.android.flexbox.FlexboxLayout>
これを実行すると以下のようになります。
各種属性については後でまとめるが、ここで使用しているものについてまずは説明します。
8行目、flexDirectionがまず重要で、子Viewの並び方向を指定します。ここではrow(行)を指定しているので、子Viewが横方向に並びます。
逆に、column
を指定すると縦方向に並びます。
9行目、flexWrapは、子Viewの並びの自動折り返し有無を指定します。 ここではnowrap
を指定しているので自動折り返しは行わず、子Viewが一行に入りきらない場合でも無理やり幅を調整して詰め込んでいます。
ちなみにwrapを指定すると、以下のように子Viewのサイズを変更せず自動で折り返します。
最後のViewが折り返している。中央に来ているのは次のjustifyContentがcenterのため。
11行目、justifyContentは子Viewの並び方向への子Viewの張り付き位置を指定します。ここではcenter
を指定してるので、真ん中に張り付きます(便宜上TextViewを減らしてます)。flex_start
だと並び方向の先頭位置に張り付きます。
space_betweenはViewの間にスペースを入れてViewの並び方向いっぱいに広がります。
space_aroundはViewの前後(columnだと上下)にそれぞれスペースを入れ、Viewの並び方向に広がります。
flex_startを指定した場合
9行目、flexWrapは、子Viewの並びの自動折り返し有無を指定します。 ここではnowrap
を指定しているので自動折り返しは行わず、子Viewが一行に入りきらない場合でも無理やり幅を調整して詰め込んでいます。
ちなみにwrapを指定すると、以下のように子Viewのサイズを変更せず自動で折り返します。
10行目、alignItemsは、子Viewを並べる方向(ここでは横)と交差する方向(ここでは縦)に対する、Viewの張り付き位置を指定します。flex_start
は開始位置(ここでは一番上部)に張り付きます。
flex_end
は逆に一番下に張り付きます(下図)。Center
だと中央に張り付きます。
ここまではFlexboxLayoutの属性について説明しましたが、各子Viewにも個別に指定できる属性があります。
(・・・・略・・・) <TextView android:text="Hello World!1" android:layout_width="80dp" android:layout_height="80dp" android:background="#0000FF" app:layout_alignSelf="flex_end"/> (・・・・略・・・)
layout_alignSelfはalignItemsの個別版のような感じです。実行すると以下のように、"Hello World!1"だけが一番下に張り付きます。
各属性について
他の属性も合わせて簡単に概要をまとめました。
属性 | 概要 |
---|---|
flexDirection | 子Viewの並び方向 |
flexWrap | 子Viewの並び方向への折り返し有無 |
justifyContent | 子Viewの並び方向へのViewの張り付き位置 |
alignItems | 子Viewの並び方向に対して交差する方向に子Viewを貼り付ける。 |
layout_order | 子Viewの並び順を指定。数値の小さい順に並ぶ。デフォルトは1。 |
layout_flexGrow | 子Viewを配置した結果の残りの空間に対して、子Viewが伸長する割合。伸長方向は子Viewの並び方向。デフォルトは0。 |
layout_flexShrink | layout_flexGrowとは逆に、収縮具合を指定。デフォルトは1。 |
layout_alignSelf | 子Viewの並び方向に対して交差する方向にViewの貼り付け位置を指定。 |
layout_flexBasisPercent | 子Viewの並び方向に対して、layout_flexBasisPercentを指定された子Viewが親Viewに対して占める割合。 |
<?xml version="1.0" encoding="utf-8"?> <com.google.android.flexbox.FlexboxLayout 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:id="@+id/flexbox_layout" app:flexDirection="row" app:flexWrap="nowrap" app:alignItems="flex_start" app:justifyContent="space_around"> <TextView android:text="Hello World!1" android:layout_width="80dp" android:layout_height="80dp" android:background="#0000FF" app:layout_flexGrow="0.1"/> <TextView android:text="Hello World!2" android:layout_width="80dp" android:layout_height="80dp" android:background="#FFFF00" app:layout_order="0" app:layout_flexGrow="0.2" /> </com.google.android.flexbox.FlexboxLayout>
言葉では少し伝わりにくいと思いますが、実はこのあたりもW3Cのドキュメントを見ると下図のように図でわかりやすく解説されています。属性の名称も似ているので、非常に参考になります。
今日のところは以上です。