はじめに
参考になったのはこちらの2記事でした。
- iOSのハーフモーダルをAndroidでも実装してみた(Kotlin+BottomSheetBehavior)
- 【Android】GoogleマップアプリのようなBottomSheet(画面下部のメニュー)を作る
実装したコードと説明
全量は こちら に
ポイント
Google のロゴをスライドに合わせて移動させてます。
(GoogleMap風に..)
xmlではanchorも指定していますが、
anchorは若干マージンの幅がずれたりするので、
onSlideで計算した方が良い感じになります。
計算が手動になりますが、滑らかに動く分計算して実装できるといい感じです。
閉じているとき
広げたとき
MapsActivity.kt
// CoordinatorLayout の 直下に配置している View を渡す
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottomSheetLayout))
bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
Log.d("tag", "slideOffset=$slideOffset")
// 異常値を弾く
if (slideOffset > 1 || slideOffset < -1) {
return
}
val minHeight = 56 // peek_height
val slide = 300 - minHeight // 最大の高さから最低の高さを引いたのが移動幅
val defaultBottomMargin = 8 // 最低bottomマージン
val bottomMargin = (slide * slideOffset + minHeight + defaultBottomMargin).toInt()
mMap.setPadding(0 ,0, 0, dp2px(bottomMargin))
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
}
})
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
activity_maps.xml
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="72dp"
android:layout_marginEnd="16dp"
android:layout_gravity="top|end"
android:orientation="vertical"
app:layout_anchorGravity="top|end"
app:layout_anchor="@id/bottomSheetLayout">
<Button
android:id="@+id/buttonMyHouse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自宅" />
<Button
android:id="@+id/buttonMyOffice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="勤務先" />
</LinearLayout>
最後に
iOSとandroidでの違いとか部品名が意外とわからない、あとGoogleのアプリ使ってるとできること(できそうなこと)、Googleが提供している部品かどうかがわかるのでやっぱり使い倒すの大事だなと。