class: chapter-1, hero, center, middle #
Design Support Library
droid girls meetup 2016/11/16 荒木佑一 --- class: chapter-1, normal # 自己紹介 .card[ 荒木佑一 [@yuichi_araki](https://twitter.com/yuichi_araki) Developer Programs Engineer @Google - サポート ライブラリ (主に design) - Google I/O アプリ - Google Santa Tracker アプリ - [d.android.com/samples](http://d.android.com/samples) のサンプルいろいろ - [CameraView](https://github.com/google/cameraview) ] --- class: chapter-2, hero, middle, center # サポート ライブラリ --- class: chapter-2, normal # サポート ライブラリとは .card[ Android アプリに組み込むライブラリ Android プラットフォーム本体と並行して開発される - プラットフォーム本体の機能のバックポート - プラットフォーム本体には存在しない追加の機能 最新版 25.0.1 ] ??? - Web の世界では "shim" や "polyfill" と呼ばれるもの - 当初は API レベル間の互換性のためのライブラリだったが、今はいろいろ --- class: normal, chapter-2 # サポート ライブラリ 一覧 .card[ .small[ - インフラ互換性: support-v4, support-v13, support-annotations, vector-drawable, animated-vector-drawable, transition - UI 互換性: appcompat-v7, preferences-v7, preferences-v14, gridlayout-v7 - UI ライブラリ: recyclerview-v7, design, percent, cardview-v7 - その他: palette-v7, customtabs, renderscript-v8, mediarouter-v7, leanback-v17, recommendation, preference-leanback-v17 - 特殊: Testing Support Library (Espresso 含む), Data Binding, MultiDex, constraint-layout ] ] ??? - 20 個と少し - 「特殊」は他のサポート ライブラリとバージョンが別 --- class: normal, chapter-2 # 導入方法 .card[ app/build.gradle ```groovy android { compileSdkVersion `25` ... } dependencies { compile 'com.android.support:design:`25`.0.1' } ``` ] ??? - compileSdkVersion とサポート ライブラリのメジャー バージョンは揃えること - 揃えない使い方は想定もテストもしていません --- class: normal, chapter-2 # 複数のサポート ライブラリ .card[ app/build.gradle ```groovy ext { supportLibVersion = '25.0.1' } dependencies { compile "com.android.support:design:${supportLibVersion}" compile "com.android.support:cardview-v7:${supportLibVersion}" } ``` ] --- class: normal, chapter-2 # 依存関係 .card[ .large[![依存関係](dependencies.png)] ] ??? - 一部割愛 --- class: chapter-3, hero, middle, center # サポート ライブラリ
チームからの
お知らせ --- class: chapter-3, normal # 最小 SDK バージョン .card[ ライブラリ名の後ろやパッケージ名に付いている v4 や v7 - support-v4 - appcompat-v7 ~~そのライブラリがサポートする最小 API レベル~~ すべてのライブラリの最小 SDK バージョンは最低でも 9 v4, v7 は歴史的経緯 ] ??? - バージョン 24.2.0 のアップデートで、すべてのライブラリの最小 SDK バージョンが 9 以上になった - support-v4、各種 -v7、design - 前から 9 より上だったものはそのまま - パッケージ名の v4 や v7 も同様 --- class: chapter-3, normal # support-v4 の分割 .card[ - support-compat - support-core-ui - support-core-utils - support-fragment - support-media-compat [分割されたv4 Support Librariesのリスト](http://androhi.hatenablog.com/entry/2016/08/19/011805) ] ??? - バージョン 24.2.0 のアップデートで分割された - support-v4 はメタ ライブラリとして残る - ほとんどのアプリはそのままで良い --- class: chapter-3, normal # バグ報告 機能要望 .card[ ## b.android.com スクリーンショット重要 ] --- class: chapter-4, hero, middle, center # マテリアル デザイン
サポート ライブラリ --- class: chapter-4, normal # デザイン サポート ライブラリ .card[ ![cheesesquare](design-cheesesquare.png) マテリアル デザインで使われるコンポーネント群 API レベル 7 からサポート appcompat-v7 の使用が前提 [github.com/chrisbanes/cheesesquare](https://github.com/chrisbanes/cheesesquare) ] ??? - Google I/O 2015 で発表 --- class: chapter-5, normal # NavigationView .card[ ![NavigationView](design-navigationview.png) ナビゲーション ドロワーの中のメニューをリソースで作ることができる ```xml <a.s.d.w.NavigationView android:id="@+id/nav_view" android:layout_height="match_parent" android:layout_width="wrap_content" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header" `app:menu="@menu/drawer_view"`/> ```
] ??? - セクション分け、セクションのサブタイトルなどに対応 - app:actionLayout 属性でカスタム要素を追加できる - 例: Gmail の未読数、Google Play Music の「ダウンロード済み」のスイッチなど --- class: chapter-5, normal # NavigationView のメニュー .card[ ```xml <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/nav_home" android:icon="@drawable/ic_dashboard" android:title="Home" app:actionLayout="@layout/action_layout.xml" /> <!-- ... --> </group> <item android:title="Sub items"> <menu> <item android:icon="@drawable/ic_dashboard" android:title="Sub item 1" /> ``` ] ??? - グループ分け - サブヘッダー - actionLayout --- class: chapter-6, normal # BottomNavigationView .card[ ![BottomNavigationView](design-bottomnavigationview.png) 「下タブ」 ```xml <a.s.d.w.BottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="match_parent" android:layout_height="56dp" android:layout_gravity="bottom" android:background="#eee" `app:menu="@menu/bottom_menu"`/> ``` ] ??? 項目数 - 3
固定 (アクティブな項目は少し拡大) - 4, 5
アニメーション (テキストはアクティブな項目のみ) - 6
エラー --- class: chapter-6, normal # BottomNavigationView のメニュー .card[ ```xml <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_search" android:title="@string/menu_search" android:icon="@drawable/ic_search"/> <item android:id="@+id/action_settings" android:title="@string/menu_settings" android:icon="@drawable/ic_add"/> <item android:id="@+id/action_music" android:title="@string/tab_text" android:icon="@drawable/ic_action_navigation_menu"/> </menu> ``` ] --- class: chapter-6, normal # BottomNavigationView のリスナー .card[ ```java final BottomNavigationView bottom = ...; bottom.setOnNavigationItemSelectedListener( new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected( @NonNull MenuItem item) { switch (item.getItemId()) { case R.id.action_search: // ... } } }); ``` ] ??? - タブ切り替えによって中のメイン画面をどう切り替えるはアプリ任せ --- class: chapter-7, normal # TabLayout .card[ ![TabLayout](design-tablayout.png) ViewPager (support-v4) と連携するタブ ```java tabLayout.`setupWithViewPager(viewPager)`; ``` ] ??? - 昔は ActionBar のナビゲーションモードでタブを作っていた - API レベル 21 で deprecated になった --- class: chapter-8, normal # TextInputLayout .card[ ![TextInputLayout](design-textinputlayout.png) EditText に機能追加
ヒント、エラー、カウンター ```xml <a.s.d.w.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:counterEnabled="true" app:counterMaxLength="30"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/description"/> </a.s.d.w.TextInputLayout> ``` ] ??? - ヒントは EditText のヒントからアニメーションでフロート表示になる - counterMaxLength は EditText の maxLength と違って、最大文字数を超えて入力できる --- class: chapter-9, normal # FloatingActionButton .card[ ![FloatingActionButton](design-floatingactionbutton.png) FAB 影付きの丸い ImageButton ```xml <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fabSize="normal" android:src="@drawable/ic_done" /> ``` ] ??? - API レベルの違いによる影の扱いは CardView と同じ --- class: chapter-10, normal # Snackbar .card[ ![Snackbar](design-snackbar.png) Toast の進化版 アクションを設定できる ```java Snackbar.make(view, "Here's a Snackbar", Snackbar.LENGTH_LONG) .setAction("Action", new View.OnClickListener() { @Override public void onClick(View v) { // ... } }) .show(); ``` ] ??? - 使い方は大体 Toast と同じ - show を忘れると出ないので注意 - 一つ目の引数は Context でなく View - 親を辿っていって CoordinatorLayout があればそこに Snackbar の View を出す - なければ適当に出す - setAction でアクションを設定できる --- class: chapter-11, normal # CoordinatorLayout .card[ 超すごい FrameLayout - Behavior
子要素同士の挙動を取り持つ - Keyline
複数の子要素を縦に並べる - Anchor
ある子要素を別の子要素にくっつける - View Inset
ある子要素が別の子要素を避ける/避けさせる ] --- class: chapter-12, normal # AppBarLayout .card[ ![AppBarLayout](design-appbarlayout.png) スクロールに従って Toolbar を隠す ```xml <a.s.d.w.CoordinatorLayout> <a.s.d.w.AppBarLayout> <a.s.v7.w.Toolbar app:layout_scrollFlags ="scroll|enterAlways|snap"/> <a.s.d.w.TabLayout/> </a.s.d.w.AppBarLayout> </a.s.d.w.CoordinatorLayout> ``` ] --- class: chapter-13, normal # CollapsingToolbarLayout .card[ ![CollapsingToolbarLayout](design-collapsingtoolbarlayout.png) Toolbar に動きを加える ```xml <a.s.d.w.CoordinatorLayout> <a.s.d.w.AppBarLayout> <a.s.d.w.CollapsingToolbarLayout app:layout_scrollFlags ="scroll|exitUntilCollapsed"> <ImageView app:layout_collapseMode="parallax"/> <a.s.v7.w.Toolbar app:layout_collapseMode="pin"/> </a.s.d.w.CollapsingToolbarLayout> </a.s.d.w.AppBarLayout> </a.s.d.w.CoordinatorLayout> ``` ] ??? - cheesesquare のようにタイトル文字を動かしたい場合、CollapsingToolbarLayout に setTitle しないといけないので注意 --- class: chapter-14, normal # BottomSheetBehavior .card[ ![Bottom Sheet](bs-design.png) マテリアル デザインの [ボトム シート](https://www.google.com/design/spec/components/bottom-sheets.html) コンポーネントの実装 - Persistent - Hideable - Modal
] ??? - 使い方が大きく分けて 3 パターン --- class: normal, chapter-14 # 実用例 .card[ ![サンタ トラッカー](bs-santatracker.webp) [Google サンタ トラッカー](https://play.google.com/store/apps/details?id=com.google.android.apps.santatracker) Persistent なボトムシート CoordinatorLayout の anchor 機能で FAB をボトムシートの上端に留める ボトム シートが引き上げられたときは FAB を隠す
] --- class: normal, chapter-14 # Persistent な BottomSheetBehavior .card[ ```xml <android.support.design.widget.CoordinatorLayout> <!-- 他の View --> <FrameLayout android:id="@+id/bottom_sheet" android:layout_width="match_parent" android:layout_height="match_parent" android:background="?android:attr/windowBackground" `app:layout_behavior="@string/bottom_sheet_behavior"` `app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"`> <!-- ボトム シートの中身 --> </FrameLayout> </android.support.design.widget.CoordinatorLayout> ``` ] ??? - どんな View でもボトム シートにできる - BottomSheet や BottomSheetView というクラスはない - CoordinatorLayout の Behavior - ボトムシート内のスクロールする部分は NestedScrollView か RecyclerView - NestedScrollingChild を継承したもの --- class: normal, chapter-14 # Hideable な BottomSheetBehavior .card[ ```xml <android.support.design.widget.CoordinatorLayout> <!-- 他の View --> <FrameLayout android:id="@+id/bottom_sheet" android:layout_width="match_parent" android:layout_height="match_parent" android:background="?android:attr/windowBackground" app:layout_behavior="@string/bottom_sheet_behavior" app:behavior_peekHeight="@dimen/bottom_sheet_peek_height" `app:behavior_hideable="true"`> <!-- ボトム シートの中身 --> </FrameLayout> </android.support.design.widget.CoordinatorLayout> ``` ] --- class: normal, chapter-14 # BottomSheetBehavior のコールバック .card[ 状態が変わった時とスライドした時 ```java BottomSheetBehavior behavior = BottomSheetBehavior.from( (FrameLayout) findViewById(R.id.bottom_sheet)); behavior.setBottomSheetCallback( new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, @BottomSheetBehavior.State int newState) { // ... } @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { // ... } }); ``` ] --- class: normal, chapter-14 # Modal な BottomSheetBehavior .card[ ![Modal Bottom Sheet](bs-design.png) ## BottomSheetDialogFragment 通常の (AppCompat)DialogFragment と使い方は同じ スクロール部分は NestedScrollView や RecyclerView を使うこと (ScrollView や ListView はダメ)
] --- class: chapter-17, hero # バグ・機能要望 ## b.android.com ### スクリーンショット重要