〈kotlin〉 BottomSheet
Android studioでkotlinを使ってAndroidアプリ作成の勉強中。
Material DesignのBottomSheetをサンプルコードをもとに作成してみた。
Material Design
BottomSheetはこういう下から出てくるビューのこと。
標準的なBottomSheet
<androidx.coordinatorlayout.widget.CoordinatorLayout ...> <Button android:id="@+id/buttonBottomSheetPersistent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="Open Persistent Bottom Sheet" /> <LinearLayout android:id="@+id/persistent_bottom_sheet" ... //レイアウトをBottomSheetとして定義する app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" app:behavior_hideable="true" //完全に隠れるようにするかどうか app:behavior_peekHeight="30dp" // 表示される高さ> //以下にBottomSheetに表示するビューを配置 <TextView android:id="@+id/content1" ... /> <TextView android:id="@+id/content2" ... /> <TextView android:id="@+id/content3" .../> </LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
設定にapp:layout_behaviorを追加してBottomSheetとして定義する。
その他追加したいBottomSheetの設定があれば、
app:layout_behaviorを追加したビューに設定するか、
Activityで呼び出して(以下のコードの*部分)設定する。
class MainActivity : AppCompatActivity() { private lateinit var binding : ActivityPersistentBottomSheetBinding private lateinit var bottomSheetBehavior:BottomSheetBehavior<LinearLayout> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityPersistentBottomSheetBinding.inflate(layoutInflater) setContentView(binding.root) //* //BottomSheetを取得して設定を追加できるようにする bottomSheetBehavior = BottomSheetBehavior.from(binding.persistentBottomSheet) //状態の変化やスライド操作によるコールバックを登録できる bottomSheetBehavior.addBottomSheetCallback(object :BottomSheetBehavior.BottomSheetCallback() { override fun onSlide(bottomSheet: View, slideOffset: Float) { } override fun onStateChanged(bottomSheet: View, newState: Int) { binding.buttonBottomSheetPersistent.text = when (newState) { //BottomSheetが閉じているか開いているかを表すStateをもとにボタンの文字を変える BottomSheetBehavior.STATE_EXPANDED -> "Close Persistent Bottom Sheet" BottomSheetBehavior.STATE_COLLAPSED -> "Open Persistent Bottom Sheet" else -> "Persistent Bottom Sheet" } } }) //BottomSheetを閉じたり開いたりするボタン binding.buttonBottomSheetPersistent.setOnClickListener { val state = if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) BottomSheetBehavior.STATE_COLLAPSED else BottomSheetBehavior.STATE_EXPANDED bottomSheetBehavior.state = state } } }
Modal Bottom Sheet
BottomSheetとして表示するFragmentを別で用意する。
設定はstyle.xml内に記述する。
<style name="ModalBottomSheet" parent="Widget.MaterialComponents.BottomSheet.Modal"> <!-- Apply attributes here --> </style> <style name="ModalBottomSheetDialog" parent="ThemeOverlay.MaterialComponents.BottomSheetDialog"> <item name="bottomSheetStyle">@style/ModalBottomSheet</item> </style> <style name="AppTheme" parent="Theme.MaterialComponents.*"> <item name="bottomSheetDialogTheme">@style/ModalBottomSheetDialog</item> </style>
<androidx.constraintlayout.widget.ConstraintLayout ... android:id="@+id/modal_bottom_sheet"/> <TextView android:id="@+id/layout_edit" .../> <TextView android:id="@+id/layout_delete" .../> <TextView android:id="@+id/layout_add" .../> </androidx.constraintlayout.widget.ConstraintLayout>
class BottomSheetFragment : BottomSheetDialogFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_bottom_sheet, container, false) } companion object{ const val TAG = "BottomSheet" } }
ActivityでBottomSheetを追加する。
class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { ... binding.bottomSheetButton.setOnClickListener { val bottomSheetFragment = BottomSheetFragment() bottomSheetFragment.show(supportFragmentManager, BottomSheetFragment.TAG) /* コード上でbehaviorの属性を追加する場合は以下のように取得する val modalBottomSheetBehavior = (bottomSheetFragment.dialog as BottomSheetDialog).behavior */ } } }
参考
Material Design
Bottom Sheet Android Tutorial - Working with BottomSheet