Material Design 设计规范は Google I/O 2014 で発表され、このデザイン理念は発表されるや否や多くの開発者に愛されました。主に紙の質感を強調し、デザインの実体感を際立たせることに重点を置いており、デザインをより現実世界に近づけ、滑らかで連続的なインタラクションとユーザー体験を追求しています。このデザイン規範は Android エコシステムの発展を促進するものであり、そのために Google は FloatingActionButton、Snackbar、TabLayout など、Material Design スタイルに合った一連のコントロールを提供しています。開発中によく使用されますが、記録を取っていなかったため、これらのコンポーネントの使用を一から記録しようと思います。今日は CoordinatorLayout と FloatingActionButton に関連する知識について説明します。主な内容は以下の通りです:
- CoordinatorLayout
- FloatingActionButton
- FloatingActionButton の属性
- 簡単な使用法
CoordinatorLayout#
CoordinatorLayout は強化版の FramLayout であり、制限を加えない場合、CoordinatorLayout 内の子 View はデフォルトで左上隅に表示されます。CoordinatorLayout には主に二つの使用方法があります:
- アプリのトップレベルレイアウトとして
- 一つまたは複数の子 View とインタラクションするコンテナとして
CoordinatorLayout 内の子 View に Behavior を指定することができ、単一の親レイアウト内で多くの異なるインタラクション効果を提供します。子 View 同士も相互にインタラクションが可能で、CoordinatorLayout は CoordinatorLayout.DefaultBehavior アノテーションを使用して子 View のデフォルトの動作を指定できます。要するに、CoordinatorLayout を利用して異なるスクロール効果を実現できます。
FloatingActionButton#
FloatingActionButton は Material Design タイプのボタンコントロールで、一般的には UI の上層に浮かぶ円形のアイコンとして表示されます。独自の behavior を持ち、アンカーを設定することができます。
FloatingActionButton には二つのサイズがあり、それぞれ normal (56dp) と mini (40dp) です。デフォルトは mini (40dp) で、そのサイズは属性 fabSize を使用して指定できます。また、fabSize を auto に設定すると、システムが異なる画面に応じて適切なサイズを選択します。
FloatingActionButton は間接的に ImageView を継承しており、以下のようにコード内でアイコンを設定できます:
//アイコンを設定
fab.setImageDrawable(getResources().getDrawable(R.drawable.fab));
fab.setImageResource(R.drawable.fab);
FloatingActionButton の背景色はデフォルトでテーマの colorAccent に設定されています。コード内で FloatingActionButton の背景色を変更するには、以下のようにします:
//背景色を設定
fab.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#000000")));
以下のように FloatingActionButton のサイズを設定できます:
//サイズを設定
fab.setSize(FloatingActionButton.SIZE_MINI);
では、FloatingActionButton のサイズをカスタマイズするにはどうすればよいのでしょうか。FloatingActionButton の一部のソースコードから、そのサイズを決定する寸法が dimens ファイルに定義されていることがわかります。具体的には design_fab_size_mini と design_fab_size_normal によって決まります。部分的なコードは以下の通りです:
//ソースコード
private int getSizeDimension(@Size final int size) {
final Resources res = getResources();
switch (size) {
case SIZE_AUTO:
// 自動に設定されている場合、リソースからサイズを取得して更新
final int width = res.getConfiguration().screenWidthDp;
final int height = res.getConfiguration().screenHeightDp;
return Math.max(width, height) < AUTO_MINI_LARGEST_SCREEN_WIDTH
? getSizeDimension(SIZE_MINI)
: getSizeDimension(SIZE_NORMAL);
case SIZE_MINI:
return res.getDimensionPixelSize(R.dimen.design_fab_size_mini);
case SIZE_NORMAL:
default:
return res.getDimensionPixelSize(R.dimen.design_fab_size_normal);
}
}
したがって、dimens フォルダーを作成し、その中で design_fab_size_mini と design_fab_size_normal の値を再設定することで FloatingActionButton のサイズをカスタマイズできます。具体的には以下の通りです:
/**dimens.xml**/
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="design_fab_size_mini" tools:override="true">20dp</dimen>
<dimen name="design_fab_size_normal" tools:override="true">100dp</dimen>
</resources>
もちろん、FloatingActionButton は間接的に ImageView を継承しているため、ImageView のいくつかの属性も使用できますが、ここでは詳しくは述べません。
FloatingActionButton の属性#
以下は一般的に使用される属性のいくつかです:
android:src //アイコンを設定(24dp)
app:backgroundTint //アイコンの背景色を設定
app:rippleColor //クリック時の水波紋の色を設定
app:elevation //影の大きさを設定
app:fabSize //サイズを設定
app:pressedTranslationZ //押下時の Z 軸からの距離を設定
app:layout_anchor //アンカーを設定
app:layout_anchorGravity//相対的なアンカーの位置を設定
属性について理解を深め、具体的な使用時に設定後の効果を観察することは直感的な学習方法の一つです。
簡単な使用法#
やはりノートを取るなら効果的な画像があった方が良いと思うので、CoordinatorLayout と FloatingActionButton を簡単に使用して具体的な効果を見てみましょう。レイアウトは以下の通りです:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.manu.materialdesignsamples.samples.SampleActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:visibility="visible"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:layout_gravity="bottom|end"
android:src="@drawable/fab"
android:scaleType="center"
app:backgroundTint="@color/colorAccent"
app:backgroundTintMode="src_in"
app:elevation="5dp"
app:rippleColor="#000000"
app:fabSize="auto"
app:pressedTranslationZ="10dp"/>
</android.support.design.widget.CoordinatorLayout>
次に、FloatingActionButton のクリックイベントを設定します。具体的には以下の通りです:
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(v,"私はSnackbar...",Snackbar.LENGTH_SHORT)
.setAction("キャンセル", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(SampleActivity.this, "キャンセル", Toast.LENGTH_SHORT).show();
}
}).show();
}
});
まずは効果の画像を一枚、具体的には以下の通りです:
FloatingActionButton は自動的に Snackbar に位置を確保し、Snackbar が表示されるときに FloatingActionButton を隠さないようにします。なぜなら、FloatingActionButton 内部では Snackbar に対応する Behavior がすでに実装されており、CoordinatorLayout は対応する Behavior の具体的な動作に基づいて子 View の位置を自動的に調整します。ここではもちろん FloatingActionButton の位置が調整されます。ルートレイアウトを RelativeLayout に設定してみると、Snackbar が表示されると FloatingActionButton が隠れてしまうことがわかります。言うまでもなく、CoordinatorLayout は調整レイアウトであり、Behavior の部分については後で整理します。今日はここまでにします。