Android Kotlin基礎講座 10.2:マテリアルデザイン、ディメンション、カラー
目次
タスク:フローティングアクションボタン(FAB)を追加する
このタスクでは、フローティングアクションボタン(FAB)をGDG Finderアプリのホーム画面に追加します。
FABは大きな丸いボタンでユーザーが画面上で行う主なアクションをまとめることができます。FABは以下のスクリーンショット(左)で表されているように、全てのコンテンツの上に表示されます。ユーザーがFABをタップすると、スクリーンショット(右)のようにGDGsのリストに遷移します。
ステップ1:ホームフラグメントにFABを追加する
- この記事のスターターアプリであるGDGFinderStylesをダウンロードして起動してください。もし前回の記事を完了している場合は、前回のアプリを引き続き使えます。
- build.gradle(Module: app)内でマテリアルライブラリが含まれていることを確認します。マテリアルデザインコンポーネントを使うには、このライブラリが含まれている必要があります。最新のライブラリバージョンを使っていることを確認してください。
implementation 'com.google.android.material:material:1.2.0'
- res/layout/home_fragment.xmlを開いて、テキストタブに切り替えてください。
現在、ホーム画面のレイアウトはConstraintLayoutを子とする単体のScrollViewを使っています。FABをConstraintLayoutに追加すると、FABはConstraintLayout内にあることになるので、全てのコンテンツの上には表示されず、ConstraintLayoutのコンテンツ以外のものと一緒にスクロールしてしまうことになります。FABを現在のレイアウトの全てのコンテンツの上に表示する必要があります。
CoordinatorLayoutはビューをお互いに積み重ねることができるビューグループです。
CoordinatorLayoutには派手なレイアウト機能はありませんが、このアプリには十分です。
ScrollViewは画面全体に、FABは画面下端に表示される必要があります。 - home_fragment.xml内、ScrollViewの周りにCoordinatorLayoutを追加してください。
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
...
</androidx.coordinatorlayout.widget.CoordinatorLayout>
- <ScrollView>を<androidx.core.widget.NestedScrollView>で置き換えてください。コーディネーターレイアウトはスクロールを認識しているため、スクロールを正しく機能させるには、スクロールを使用している別のビュー内でNestedScrollViewを使用する必要があります。
androidx.core.widget.NestedScrollView
- CoodinatoryLayout内、NestedScrollViewの下にFloatingActionButtonを追加してください。
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
- アプリを起動してください。左上に色の付いた丸が表示されるはずです。
- ボタンをタップしてください。ボタンが見た目で反応していることを確認してください。
- ページをスクロールしてください。ボタンが画面上に固定されていることを確認してください。
ステップ2:FABをスタイリングする
このステップでは、FABを右下端に移動させ、FABのアクションを示す画像を追加します。
- home_fragment.xml内、layout_gravity属性をFABに追加し、ボタンをbottomかつendに移動しましょう。layout_gravity属性はビューに対して、top、bottom、start、end、centerなどに配置するようにレイアウト情報を伝えます。パイプライン(|)を使って、これらを組み合わせることもできます。
android:layout_gravity="bottom|end"
- プレビューでボタンの位置が変わっていることを確認しましょう。
- FABに16dpのlayout_marginを追加して、画面の端から少し空間をあけます。
android:layout_margin="16dp"
- FAB用の画像として、あらかじめ提供されているic_gdgアイコンを使用しましょう。以下のコードを追加すると、FABの中に山なりのマークが現れます。
app:srcCompat="@drawable/ic_gdg"
- アプリを起動してください。以下のスクリーンショットのようになっているはずです。
ステップ3:FABにクリックリスナーを追加する
このステップでは、ユーザーをGDGsのリスト画面に遷移させるためのクリック処理をFABに追加します。クリック処理については以前の記事で解説しているので、ここでは簡潔に進めます。
- home_fragment.xml内、<data>タグの中で、提供されているHomeViewModelを格納するための変数viewModelを定義してください。
<variable
name="viewModel"
type="com.example.android.gdgfinder.home.HomeViewModel"/>
- FABにonClickリスナーを追加し、onFabClicked()と命名します。
android:onClick="@{() -> viewModel.onFabClicked()}"
- homeパッケージ内のHomeViewModelクラスを開いて、以下に示されているナビゲーションのLiveDataとその機能を確認してください。FABがクリックされると、onFabClicked()が呼び出され、ナビゲーションを促します。
private val _navigateToSearch = MutableLiveData<Boolean>()
val navigateToSearch: LiveData<Boolean>
get() = _navigateToSearch
fun onFabClicked() {
_navigateToSearch.value = true
}
fun onNavigatedToSearch() {
_navigateToSearch.value = false
}
- homeパッケージ内、HomeFragmentクラスを開いてください。onCreateView()がHomeViewModelを作成し、それをviewModelに代入していることを確認してください。
- viewModelをonCreateView()のbindingに追加してください。
binding.viewModel = viewModel
- エラーを排除するために、プロジェクトをクリーン・リビルドしてバインディングオブジェクトを更新しましょう。
- onCreateView()内でGDGsのリストに遷移させるオブザーバーを追加してください。
viewModel.navigateToSearch.observe(viewLifecycleOwner,
Observer<Boolean> { navigate ->
if(navigate) {
val navController = findNavController()
navController.navigate(R.id.action_homeFragment_to_gdgListFragment)
viewModel.onNavigatedToSearch()
}
})
- androidxから必要なものをインポートしてください。findNavControllerとObserverは以下をインポートしてください。
import androidx.navigation.fragment.findNavController
import androidx.lifecycle.Observer
- アプリを起動してください。
- FABをタップするとGDGのリストに遷移します。もしアプリを物理デバイスで起動している場合は、位置情報の許可を求められます。エミュレーターで起動している場合は以下のようなメッセージと空白のページが表示されます。
エミュレーターで上記のメッセージが表示されたら、インターネットに接続されていることを確認して、位置情報をONにしてください。