@@ -24,27 +24,29 @@ import androidx.lifecycle.ViewTreeViewModelStoreOwner
24
24
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
25
25
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
26
26
import com.google.android.material.bottomsheet.BottomSheetBehavior
27
+ import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
27
28
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
28
29
import com.google.android.material.bottomsheet.BottomSheetDialog
29
30
import java.util.*
30
31
31
32
32
33
/* *
33
- * Properties used to customize the behavior of a [Dialog ].
34
+ * Properties used to customize the behavior of a [BottomSheetDialog ].
34
35
*
35
36
* @property dismissOnBackPress whether the dialog can be dismissed by pressing the back button.
36
37
* If true, pressing the back button will call onDismissRequest.
37
38
* @property dismissOnClickOutside whether the dialog can be dismissed by clicking outside the
38
39
* dialog's bounds. If true, clicking outside the dialog will call onDismissRequest.
40
+ * @property dismissWithAnimation [BottomSheetDialog.setDismissWithAnimation]
39
41
* @property securePolicy Policy for setting [WindowManager.LayoutParams.FLAG_SECURE] on the
40
42
* dialog's window.
41
- * @property usePlatformDefaultWidth Whether the width of the dialog's content should be limited to
42
- * the platform default, which is smaller than the screen width.
43
+ * @property navigationBarColor Color to apply to the navigationBar.
43
44
*/
44
45
@Immutable
45
46
class BottomSheetDialogProperties constructor(
46
47
val dismissOnBackPress : Boolean = true ,
47
48
val dismissOnClickOutside : Boolean = true ,
49
+ val dismissWithAnimation : Boolean = false ,
48
50
val securePolicy : SecureFlagPolicy = SecureFlagPolicy .Inherit ,
49
51
val navigationBarColor : Color = Color .Unspecified
50
52
) {
@@ -55,6 +57,7 @@ class BottomSheetDialogProperties constructor(
55
57
56
58
if (dismissOnBackPress != other.dismissOnBackPress) return false
57
59
if (dismissOnClickOutside != other.dismissOnClickOutside) return false
60
+ if (dismissWithAnimation != other.dismissWithAnimation) return false
58
61
if (securePolicy != other.securePolicy) return false
59
62
if (navigationBarColor != other.navigationBarColor) return false
60
63
@@ -64,25 +67,26 @@ class BottomSheetDialogProperties constructor(
64
67
override fun hashCode (): Int {
65
68
var result = dismissOnBackPress.hashCode()
66
69
result = 31 * result + dismissOnClickOutside.hashCode()
70
+ result = 31 * result + dismissWithAnimation.hashCode()
67
71
result = 31 * result + securePolicy.hashCode()
68
72
result = 31 * result + navigationBarColor.hashCode()
69
73
return result
70
74
}
71
75
}
72
76
73
77
/* *
74
- * Opens a dialog with the given content.
78
+ * Opens a bottomsheet dialog with the given content.
75
79
*
76
80
* The dialog is visible as long as it is part of the composition hierarchy.
77
- * In order to let the user dismiss the Dialog , the implementation of [onDismissRequest] should
81
+ * In order to let the user dismiss the BottomSheetDialog , the implementation of [onDismissRequest] should
78
82
* contain a way to remove to remove the dialog from the composition hierarchy.
79
83
*
80
84
* Example usage:
81
85
*
82
- * @sample androidx.compose.ui.samples.DialogSample
86
+ * @sample com.holix.android.bottomsheetdialogcomposedemo.MainActivity
83
87
*
84
88
* @param onDismissRequest Executes when the user tries to dismiss the dialog.
85
- * @param properties [DialogProperties ] for further customization of this dialog's behavior.
89
+ * @param properties [BottomSheetDialogProperties ] for further customization of this dialog's behavior.
86
90
* @param content The content to be displayed inside the dialog.
87
91
*/
88
92
@Composable
@@ -137,7 +141,7 @@ fun BottomSheetDialog(
137
141
}
138
142
139
143
/* *
140
- * Provides the underlying window of a dialog.
144
+ * Provides the underlying window of a bottomsheet dialog.
141
145
*
142
146
* Implemented by dialog's root layout.
143
147
*/
@@ -185,10 +189,22 @@ private class BottomSheetDialogWrapper(
185
189
ViewRootForInspector {
186
190
private val bottomSheetDialogLayout: BottomSheetDialogLayout
187
191
192
+ private val bottomSheetCallbackForAnimation: BottomSheetCallback = object : BottomSheetCallback () {
193
+ override fun onSlide (bottomSheet : View , slideOffset : Float ) {
194
+ }
195
+
196
+ override fun onStateChanged (bottomSheet : View , newState : Int ) {
197
+ if (newState == STATE_HIDDEN ) {
198
+ onDismissRequest()
199
+ }
200
+ }
201
+ }
202
+
188
203
private val maxSupportedElevation = 30 .dp
189
204
190
205
override val subCompositionView: AbstractComposeView get() = bottomSheetDialogLayout
191
206
207
+
192
208
init {
193
209
val window = window ? : error(" Dialog has no window" )
194
210
window.requestFeature(Window .FEATURE_NO_TITLE )
@@ -215,18 +231,6 @@ private class BottomSheetDialogWrapper(
215
231
}
216
232
}
217
233
}
218
- this .behavior.addBottomSheetCallback(
219
- object : BottomSheetBehavior .BottomSheetCallback () {
220
- override fun onSlide (bottomSheet : View , slideOffset : Float ) {
221
- }
222
-
223
- override fun onStateChanged (bottomSheet : View , newState : Int ) {
224
- if (newState == STATE_HIDDEN ) {
225
- onDismissRequest()
226
- }
227
- }
228
- }
229
- )
230
234
231
235
/* *
232
236
* Disables clipping for [this] and all its descendant [ViewGroup]s until we reach a
@@ -285,6 +289,15 @@ private class BottomSheetDialogWrapper(
285
289
}
286
290
}
287
291
292
+ override fun setDismissWithAnimation (dismissWithAnimation : Boolean ) {
293
+ super .setDismissWithAnimation(dismissWithAnimation)
294
+ if (dismissWithAnimation) {
295
+ behavior.addBottomSheetCallback(bottomSheetCallbackForAnimation)
296
+ } else {
297
+ behavior.removeBottomSheetCallback(bottomSheetCallbackForAnimation)
298
+ }
299
+ }
300
+
288
301
fun updateParameters (
289
302
onDismissRequest : () -> Unit ,
290
303
properties : BottomSheetDialogProperties ,
@@ -296,19 +309,26 @@ private class BottomSheetDialogWrapper(
296
309
setLayoutDirection(layoutDirection)
297
310
setCanceledOnTouchOutside(properties.dismissOnClickOutside)
298
311
setNavigationBarColor(properties.navigationBarColor)
312
+ dismissWithAnimation = properties.dismissWithAnimation
299
313
}
300
314
301
315
fun disposeComposition () {
302
316
bottomSheetDialogLayout.disposeComposition()
303
317
}
304
318
305
319
override fun cancel () {
306
- onDismissRequest()
320
+ if (properties.dismissWithAnimation) {
321
+ // call setState(STATE_HIDDEN) -> onDismissRequest will be called in BottomSheetCallback
322
+ super .cancel()
323
+ } else {
324
+ // dismiss with window animation
325
+ onDismissRequest()
326
+ }
307
327
}
308
328
309
329
override fun onBackPressed () {
310
330
if (properties.dismissOnBackPress) {
311
- onDismissRequest ()
331
+ cancel ()
312
332
}
313
333
}
314
334
}
0 commit comments