# HG changeset patch # User Da Risk # Date 1709851518 14400 # Node ID f6cf2e8bf04d8e27eb4a77a2a44f327e2ce46957 # Parent 1167496633b2c3a105f24018b09707a5f0ab35ce geekdroid: add ModalBottomSheetActivity a compose based BottomSheetActivity. Deprecate BottomSheetDialogActivity diff -r 1167496633b2 -r f6cf2e8bf04d geekdroid/build.gradle.kts --- 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) + } diff -r 1167496633b2 -r f6cf2e8bf04d geekdroid/src/main/java/com/geekorum/geekdroid/app/BottomSheetDialogActivity.kt --- 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 diff -r 1167496633b2 -r f6cf2e8bf04d geekdroid/src/main/java/com/geekorum/geekdroid/app/ModalBottomSheetActivity.kt --- /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 . + */ +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() + + @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) + } + } +} diff -r 1167496633b2 -r f6cf2e8bf04d geekdroid/src/main/res/values/styles.xml --- 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 @@ false + + + diff -r 1167496633b2 -r f6cf2e8bf04d gradle/libs.versions.toml --- 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" }