geekdroid: add ModalBottomSheetActivity a compose based BottomSheetActivity.
Deprecate BottomSheetDialogActivity
--- a/geekdroid/build.gradle.kts Thu Mar 07 18:44:25 2024 -0400
+++ b/geekdroid/build.gradle.kts Thu Mar 07 18:45:18 2024 -0400
@@ -53,8 +53,13 @@
abortOnError = false
}
- dataBinding {
- enable = true
+ buildFeatures {
+ dataBinding = true
+ compose = true
+ }
+
+ composeOptions {
+ kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
}
packaging {
@@ -106,6 +111,11 @@
implementation(libs.work.runtime)
implementation(libs.preference.ktx)
+ // compose stuff
+ implementation(platform(libs.androidx.compose.bom))
+ implementation(libs.androidx.compose.material3)
+ implementation(libs.androidx.activity.compose)
+
}
--- a/geekdroid/src/main/java/com/geekorum/geekdroid/app/BottomSheetDialogActivity.kt Thu Mar 07 18:44:25 2024 -0400
+++ b/geekdroid/src/main/java/com/geekorum/geekdroid/app/BottomSheetDialogActivity.kt Thu Mar 07 18:45:18 2024 -0400
@@ -41,6 +41,7 @@
* React like a [BottomSheetDialogFragment] but is a separate [Activity].
* This allows you to launch the bottom sheet easily from another external activity.
*/
+@Deprecated("Use ModalBottomSheetActivity", replaceWith = ReplaceWith("ModalBottomSheetActivity"))
abstract class BottomSheetDialogActivity : ComponentActivity() {
private lateinit var binding: ActivityBottomSheetDialogBinding
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/geekdroid/src/main/java/com/geekorum/geekdroid/app/ModalBottomSheetActivity.kt Thu Mar 07 18:45:18 2024 -0400
@@ -0,0 +1,109 @@
+/*
+ * Geekdroid is a utility library for development on the Android
+ * Platform.
+ *
+ * Copyright (C) 2017-2024 by Frederic-Charles Barthelery.
+ *
+ * This file is part of Geekdroid.
+ *
+ * Geekdroid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Geekdroid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Geekdroid. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.geekdroid.app
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.BackHandler
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.SheetValue
+import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.runtime.*
+import androidx.lifecycle.lifecycleScope
+import com.geekorum.geekdroid.R
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.consumeEach
+import kotlinx.coroutines.launch
+
+/**
+ * React like a [BottomSheetDialogFragment] but is a separate [Activity].
+ * This allows you to launch the bottom sheet easily from another external activity.
+ * This implementation use Compose and Material3 [ModalBottomSheet]
+ *
+ * The activity should use [Theme.Geekdroid.ModalBottomSheetDialogActivity][R.style.Theme_Geekdroid_ModalBottomSheetDialogActivity]
+ * theme or equivalent to work correctly.
+ */
+open class ModalBottomSheetActivity : ComponentActivity() {
+ private var _sheetContent: @Composable ColumnScope.() -> Unit by mutableStateOf({})
+
+ private val dismissEventChannel = Channel<Unit>()
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+ val coroutineScope = rememberCoroutineScope()
+
+ LaunchedEffect(Unit) {
+ dismissEventChannel.consumeEach {
+ sheetState.hide()
+ }
+ }
+
+ BackHandler(sheetState.targetValue != SheetValue.Hidden) {
+ coroutineScope.launch {
+ sheetState.hide()
+ }
+ }
+
+ // dismiss automatically when hidden
+ var wasShown by remember { mutableStateOf(false) }
+ LaunchedEffect(sheetState.isVisible) {
+ if (sheetState.isVisible) {
+ wasShown = true
+ } else if (wasShown) {
+ finish()
+ }
+ }
+
+
+ ModalBottomSheet(
+ sheetState = sheetState,
+ onDismissRequest = {},
+ dragHandle = null,
+ windowInsets = WindowInsets(0)
+ ) {
+ _sheetContent()
+ }
+ }
+ }
+
+ fun setSheetContent(
+ content: @Composable ColumnScope.() -> Unit
+ ) {
+ _sheetContent = content
+ }
+
+ fun dismiss() {
+ lifecycleScope.launch {
+ dismissEventChannel.send(Unit)
+ }
+ }
+}
--- a/geekdroid/src/main/res/values/styles.xml Thu Mar 07 18:44:25 2024 -0400
+++ b/geekdroid/src/main/res/values/styles.xml Thu Mar 07 18:45:18 2024 -0400
@@ -42,4 +42,13 @@
<item name="android:windowTranslucentStatus">false</item>
</style>
+ <style name="Theme.Geekdroid.ModalBottomSheetDialogActivity" parent="android:Theme.Dialog">
+ <item name="android:windowIsFloating">false</item>
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+ </style>
+
+
</resources>
--- a/gradle/libs.versions.toml Thu Mar 07 18:44:25 2024 -0400
+++ b/gradle/libs.versions.toml Thu Mar 07 18:45:18 2024 -0400
@@ -1,5 +1,8 @@
[versions]
annotation = "1.7.1"
+androidx-activity = "1.8.2"
+androidx-compose-bom = "2024.02.02"
+androidx-compose-compiler = "1.5.9"
browser = "1.8.0"
constraintlayout = "2.1.4"
coordinatorlayout = "1.2.0"
@@ -25,6 +28,12 @@
[libraries]
annotation = { module = "androidx.annotation:annotation", version.ref = "annotation" }
+
+androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
+
+androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "androidx-compose-bom" }
+androidx-compose-material3 = { module = "androidx.compose.material3:material3" }
+
browser = { module = "androidx.browser:browser", version.ref = "browser" }
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" }
coordinatorlayout = { module = "androidx.coordinatorlayout:coordinatorlayout", version.ref = "coordinatorlayout" }