class: chapter-1, hero, center, middle #
逆引き
マテリアル
デザイン
DroidKaigi 2017 2017/03/09 荒木佑一 --- class: chapter-1, normal # 自己紹介 .card[ 荒木佑一 [@yuichi_araki](https://twitter.com/yuichi_araki) Developer Programs Engineer @Google - サポート ライブラリ (主に design と transition) - [d.android.com/samples](http://d.android.com/samples) のサンプルいろいろ - Android Studio のテンプレートいくつか - [CameraView](https://github.com/google/cameraview) ] --- class: chapter-2, hero, middle, center # マテリアル デザイン --- class: chapter-2, normal # マテリアル デザイン .card[ [https://material.io](https://material.io) 「デジタル体験を作り上げるための理論とリソースとツールを合わせた統合システム」 .center[
] ] ??? - Google が様々なプラットフォームで UI/UX を作ってきた知見の集大成 - Android だけでなく、各プラットフォームの性質を踏まえつつ一貫性のある体験を提供する - このセッションは Android の話です --- class: chapter-2, normal # マテリアル デザイン ガイドライン .card[ [https://material.io/guidelines/](https://material.io/guidelines/) ![マテリアル デザイン](materialdesign_introduction.png) .small[ - 概要 - Motion - Style - Layout - Components - Patterns - … ] ] ??? - ☓ 従わなくてはならないもの - ○ この内容を踏まえた上で UI/UX を作り出すもの - ただ単に従うのではなく、ガイドラインの内容となぜそのようになっているかを理解することが重要 --- class: chapter-2, normal # [What's new](https://material.io/guidelines/material-design/whats-new.html) .card[ [https://material.io/guidelines/material-design/whats-new.html](https://material.io/guidelines/material-design/whats-new.html) 随時更新されている 最近の更新 - Platforms: プラットフォームごとのバリエーション - Accessibility: 読み上げについて記載追加 ] ??? - ガイドラインは常にアップデートされている --- class: chapter-2, normal # 日本語版 .card[ マテリアル デザイン ガイドライン 日本語版 [https://material.io/jp/guidelines/](https://material.io/jp/guidelines/) PDF ] ??? - PDF --- class: chapter-2, normal # 本日の話 .card[ マテリアル デザインを形にする - あるものを活用する - カスタマイズする - 動かす - 協調動作 - 状態変化 ] --- class: chapter-3, hero, center, middle # あるものを有効活用する --- class: chapter-3, normal .condensed[ # [Components - Buttons: Floating Action Button](https://material.io/guidelines/components/buttons-floating-action-button.html) ] .card[ ![FAB](components_buttons_fab.png) - サイズは 40 または 56dp - 影 - 表示・非表示切り替えはスケール アニメーション → マテリアル デザイン
サポート ライブラリ ] --- class: chapter-3, normal # FloatingActionButton .card[ マテリアル デザイン サポート ライブラリ ```xml <android.support.design.widget.FloatingActionButton android:layout_height="wrap_content" android:layout_width="wrap_content" app:fabSize="normal" app:srcCompat="@drawable/ic_action" /> ``` ```java FloatingActionButton fab = ...; fab.show(); ... fab.hide(); ``` ] ??? - 影や形はガイドライン通り - サイズは normal (56dp) と mini (40dp) - show/hide でガイドライン通りのアニメーション --- class: chapter-3, normal # 留意点 .card[ ![FAB](components_buttons_fab.png) ライブラリを使った上での留意点 - その画面での主要なアクション - ナビゲーションに使わない - 特に重要でないアクションに利用しない - 右下でなくてもいい - 下の要素をふさいでしまわないよう注意 ] ??? - これらはライブラリでどうにかできることではない - 2つあってもいい (Google Maps: 現在地 & 経路) - 下の要素をふさぐ - 無限のリストなら大丈夫 - リストの一番下にパディングを入れる (例: Google Drive) --- class: chapter-3, normal # Components - ... .card[ - Bottom navigation (BottomNavigationView) - Bottom sheets (BottomSheetBehavior) - Buttons / FAB (AppCompatButton / FAB) - Cards (CardView) - Snackbars & toasts (Snackbar) - Tabs (TabLayout) - Text fields (TextInputLayout) - Toolbar (Toolbar) ] ??? - Components セクションの中の多くは、サポートライブラリを使えば基本的にガイドライン通り - それぞれの留意点はガイドラインで確認する --- class: chapter-3, normal # [Components - Grid lists](https://material.io/guidelines/components/grid-lists.html) .card[ ![Grid](components_grids_specs7.png) 画像や文字を含んだアイテム上にタッチ フィードバック ``` <FrameLayout android:id="@+id/item" android:layout_width="256dp" android:layout_height="256dp" * android:foreground= * "?attr/selectableItemBackground"> <!-- ImageView など --> </FrameLayout> ``` ForegroundLinearLayout で検索 ] ??? - ここからは、プラットフォームの機能を使えば簡単に実現できるのに、できていないアプリをよく見かける例 - L 以降は波紋、K 以前は色の切り替え - FrameLayout 以外で android:foreground を使うには ForegroundLinearLayout で検索 - Marshmallow 以降なら View がデフォルトでサポート - 試していないがサードパーティで ForegroundView というライブラリがあるらしい --- class: chapter-3, normal # [Patterns - Launch screens](https://material.io/guidelines/patterns/launch-screens.html) .card[ ![Launch screens](patterns_launch_screens.png) コンマ一秒でも早くユーザーが興味を持つコンテンツを見せるのが大原則 どうしても時間がかかる場合ブランディング画像を表示 ] ??? - YouTube など --- class: chapter-3, normal # [Patterns - Launch screens](https://material.io/guidelines/patterns/launch-screens.html) .card[ .small[ [https://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd](https://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd) ] ```xml <style name="Theme.MyApp.Launcher"> <item name="android:windowBackground"> @drawable/launch_screen</item> </style> ``` ```java @Override protected void onCreate(Bundle savedInstanceState) { setTheme(R.style.Theme_MyApp); // 普通の背景に戻す super.onCreate(savedInstanceState); ... ``` ] ??? - https://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd --- class: chapter-4, hero, middle, center # カスタマイズする --- class: chapter-4, normal # スタイルとテーマを理解する .card[ XML の中で `@style/foobar` と `?attr/foobar` はそれぞれどういう意味? スタイルとテーマはどう違う? FAB の色はどこから来ている? ] --- class: chapter-4, normal # 属性 .card[ スタイルやテーマの指定に利用するキー res/values/attrs.xml ```xml <declare-styleable name="FloatingActionButton"> <attr name="backgroundTint"/> <attr name="fabSize"> <enum name="auto" value="-1"/> <enum name="normal" value="0"/> <enum name="mini" value="1"/> </attr> ... </declare-styleable> ``` 型は integer, float, string, boolean, enum, flag, dimension, color, reference, fraction ] ??? - FAB の例 --- class: chapter-4, normal # スタイル .card[ 属性とその値のマッピング res/values/styles.xml ```xml <style name="Widget.MyApp.FloatingActionButton" parent="Widget.Design.FloatingActionButton"> <item name="backgroundTint">@color/add</item> <item name="fabSize">normal</item> </style> ``` 明示的な継承・暗黙的な継承 ] ??? - スタイルは親を指定して継承できる --- class: chapter-4, normal # スタイルの利用 .card[ レイアウト XML ```xml <android.support.design.widget.FloatingActionButton android:id="@+id/fab" * style="@style/Widget.MyApp.FloatingActionButton" android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_android"/> ``` ] --- class: chapter-4, normal # テーマ .card[ 属性とその値のマッピング (= スタイルと同じ) res/values/themes.xml (styles.xml) ```xml <style name="Theme.MyApp" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> ``` ] --- class: chapter-4, normal # テーマの利用 .card[ AndroidManifest.xml ```xml <activity android:name=".MainActivity" android:theme="@style/Theme.MyApp"> ... ``` ] --- class: chapter-4, normal # テーマ内の属性値の利用 .card[ レイアウト XML ```xml <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="`?attr/actionBarSize`" android:background="`?attr/colorAccent`"/> ``` ] ??? - ?attr を使うと、現在のテーマで指定されている様々な属性値を取得できる --- class: chapter-4, normal # [Components - Text fields](https://material.io/guidelines/components/text-fields.html) .card[ android.support.design.widget.TextInputLayout .large[ ![TextInputLayout](textinputlayout.png) ] エラーのテキスト色をカスタマイズする ] --- class: chapter-4, normal # 例: ドキュメントから (1/2) .card[ [TextInputLayout のリファレンス](http://d.android.com/reference/android/support/design/widget/TextInputLayout.html) で errorTextAppearance を見つける レイアウト XML ```xml <android.support.design.widget.TextInputLayout android:id="@+id/input" android:layout_width="match_parent" android:layout_height="wrap_content" `app:errorTextAppearance`="@style/TextAppearance.MyApp.Error"> ... ``` ] --- class: chapter-4, normal # 例: ドキュメントから (2/2) .card[ TextAppearance をスタイルとして作成 res/values/styles.mxl ```xml <style name="TextAppearance.MyApp.Error" parent="TextAppearance.Design.Error"> <item name="android:textColor">@color/my_error</item> </style> ``` ] --- class: chapter-4, normal # 例: ソースコードから (1/4) .card[ frameworks/support/design/res/values/styles.xml ```xml <style name="Widget.Design.TextInputLayout" parent="android:Widget"> <item name="hintTextAppearance">@style/TextAppearance.Design.Hint</item> * <item name="errorTextAppearance">@style/TextAppearance.Design.Error</item> <item name="counterTextAppearance">@style/TextAppearance.Design.Counter</item> <item name="counterOverflowTextAppearance">@style/TextAppearance.Design.Counter.Overflow</item> <item name="passwordToggleDrawable">@drawable/design_password_eye</item> <item name="passwordToggleTint">@color/design_tint_password_toggle</item> <item name="passwordToggleContentDescription">@string/password_toggle_content_description</item> </style> ``` ] --- class: chapter-4, normal # 例: ソースコードから (2/4) .card[ frameworks/support/design/res/values/styles.xml ```xml <style name="TextAppearance.Design.Error" parent="TextAppearance.AppCompat.Caption"> <item name="android:textColor">`@color/design_error`</item> </style> ``` ] --- class: chapter-4, normal # 例: ソースコードから (3/4) .card[ frameworks/support/design/res/color/design_error.xml ```xml <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:color="?android:attr/textColorTertiary"/> <item android:color="`?attr/textColorError`"/> </selector> ``` ] --- class: chapter-4, normal # 例: ソースコードから (4/4) .card[ 自分のアプリのテーマで textColorError を指定すれば良い ```xml <style name="Theme.MyApp" parent="Theme.AppCompat.Light.DarkActionBar"> ... * <item name="textColorError">#090</item> </style> ``` ] ??? - スタイルとテーマの基本を理解しておけばドキュメントやソースコードから必要な情報を見つけ出すことができる --- class: chapter-5, hero, middle, center # View 同士を強調させて動かす --- class: chapter-5, normal # Material design - Material properties .card[ ![Wrong](whatismaterial_properties_physical6.png) 複数の要素が同一の空間 (elevation) に存在してはならない
] --- class: chapter-5, normal .condensed[ # [Material design - Elevation & shadows](https://material.io/guidelines/material-design/elevation-shadows.html) ] .card[ | Elevation (dp) | Component | |:---------------|:---------------------------------| | 24 | Dialog
Picker | | 16 | Nav drawer
Modal bottom sheet | | ... | ... | | 8 | FAB
Snackbar | | ... | ... | ] ??? - 各コンポーネントの基本的な elevation がまとめられている - FAB と Snackbar はどちらも 6dp の elevation --- class: chapter-5, normal # [Components - Snackbars & toasts](https://material.io/guidelines/components/snackbars-toasts.html#snackbars-toasts-usage) .card[
Snackbar が出るときに FAB が避ける FAB を CoordinatorLayout に入れれば自動的に実現 ```java Snackbar .make(view, "Hello!", Snackbar.LENGTH_SHORT) .show(); ``` ] ??? - Snackbar.make の第一引数は CoordinatorLayout かその子供なんでも --- class: chapter-5, normal # FAB と同じように避けたい .card[ FAB と同じように、下から出てくる Snackbar を避けたい CoordinatorLayout の直下で ```xml <com.example.yourapp.CustomView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" `app:layout_dodgeInsetEdges="bottom"`/> ``` ] ??? - フラグでどの辺を避けるか指定できる --- class: chapter-5, normal # Snackbar と同じように避けさせたい .card[ Snackbar と同じように FAB などを避けさせたい CoordinatorLayout の直下で ```xml <com.example.yourapp.CustomView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|start" `app:layout_insetEdge="bottom"`/> ``` ] ??? - どの辺から避けさせるか指定できる --- class: chapter-5, normal # [Components - Bottom sheets](https://material.io/guidelines/components/bottom-sheets.html#bottom-sheets-persistent-bottom-sheets) .card[ ![Bottom sheet & FAB](components_bottomsheets_persistent6.png) ```xml <a.s.d.w.FloatingActionButton android:id="@+id/pause" android:layout_width="wrap_content" android:layout_height="wrap_content" * app:layout_anchor="@id/bottom_sheet" app:srcCompat="@drawable/ic_pause"/> ``` @id/bottom_sheet が動くに連れて追従する
] --- class: chapter-6, hero, middle, center # 状態の変化を動かす --- class: chapter-6, normal # [Motion - Transforming material](https://material.io/guidelines/motion/transforming-material.html#transforming-material-rectangular-transformation) .card[
画像の拡大縮小アニメーション どうやって実装する? - ViewPropertyAnimator? - .small[view.animate()...] - Animator? - .small[ObjectAnimator / ValueAnimator] ユーザーがアニメーション中に切り替えを繰り返す場合にどう対応する? ] --- class: chapter-6 normal # [Transition API](https://developer.android.com/training/transitions/overview.html) .card[ API レベル 19 KitKat で導入 Animator に基づいた高レベル アニメーション API ※ Activity 間の Transition だけが Transition ではない ] --- class: chapter-6 normal # Transition API の使い方 .card[ ```java ChangeBounds changeBounds = new ChangeBounds(); ... TransitionManager.beginDelayedTransition(root, changeBounds); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); lp.width = lp.height = FrameLayout.LayoutParams.WRAP_CONTENT; v.setLayoutParams(lp); ``` ] --- class: chapter-6 normal # 様々な Transition .card[ | Transition | アニメーション対象 | |:---------------------|:-----------------------| | ChangeBounds | 大きさと位置 | | ChangeTransform | scale, rotation など | | ChangeScroll | スクロール位置 | | ChangeImageTransform | ImageView の scaleType | | Fade | visibiliy | | Slide | visibiliy | | Explode | visibiliy | | TransitionSet | 組み合わせる | ] --- class: chapter-6 normal # [Motion– Choreography](https://material.io/guidelines/motion/choreography.html) .card[ .large[
] ] --- class: chapter-6, normal # Transition API の機能 .card[ ## PathMotion 弧に沿って動かす ## TransitionPropagation 複数のアニメーションの startDelay を別々に調整する ] ??? - duration, startDelay, interpolator などアニメーションの基本的な機能も使える --- class: chapter-7 normal # まとめ .card[ - マテリアル デザイン ガイドラインを読みましょう - あるものを有効活用しましょう - ライブラリ、プラットフォームの機能 - カスタマイズ - スタイルとテーマの基本を知れば自在にカスタマイズできる - コンポーネント同士の協調動作 - CoordinatorLayout が使える - 状態の変化をアニメーション - Transition API が使える ] --- class: chapter-17, hero # Android プラットフォーム # サポート ライブラリ ## b.android.com ### バグ報告、機能要望はこちらから ### ※ スクリーンショット (動画) 重要