Skip to content

Commit 8f0e406

Browse files
authored
Enhance NewModuleScript Template (#344)
1 parent 10dbf4a commit 8f0e406

File tree

8 files changed

+491
-16
lines changed

8 files changed

+491
-16
lines changed

Diff for: samples-lib/src/main/java/com/esri/arcgismaps/sample/sampleslib/components/BottomSheet.kt

+75-5
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,107 @@
1616

1717
package com.esri.arcgismaps.sample.sampleslib.components
1818

19+
import android.content.res.Configuration
1920
import androidx.compose.animation.AnimatedVisibility
2021
import androidx.compose.animation.fadeIn
2122
import androidx.compose.animation.fadeOut
2223
import androidx.compose.animation.slideInVertically
2324
import androidx.compose.animation.slideOutVertically
25+
import androidx.compose.foundation.layout.Arrangement
2426
import androidx.compose.foundation.layout.Box
27+
import androidx.compose.foundation.layout.Column
28+
import androidx.compose.foundation.layout.ColumnScope
29+
import androidx.compose.foundation.layout.Row
30+
import androidx.compose.foundation.layout.Spacer
2531
import androidx.compose.foundation.layout.fillMaxSize
32+
import androidx.compose.foundation.layout.fillMaxWidth
33+
import androidx.compose.foundation.layout.height
34+
import androidx.compose.foundation.layout.padding
35+
import androidx.compose.material.icons.Icons
36+
import androidx.compose.material.icons.filled.Close
37+
import androidx.compose.material3.FilledTonalIconButton
38+
import androidx.compose.material3.Icon
39+
import androidx.compose.material3.MaterialTheme
40+
import androidx.compose.material3.Surface
41+
import androidx.compose.material3.Text
2642
import androidx.compose.runtime.Composable
2743
import androidx.compose.ui.Alignment
2844
import androidx.compose.ui.Modifier
45+
import androidx.compose.ui.tooling.preview.Preview
46+
import androidx.compose.ui.unit.dp
47+
import com.esri.arcgismaps.sample.sampleslib.theme.SampleAppTheme
2948

3049
/**
3150
* Composable component used to display a custom bottom sheet for samples.
3251
* The bottom sheet can display any @Composable content passed to the [bottomSheetContent],
33-
* and the visibility can be toggled using [isVisible]
52+
* and the visibility can be toggled using [isVisible].
53+
*
54+
* Optionally, pass a [sheetTitle] to display a close Icon which provides an [onDismissRequest].
3455
*/
3556
@Composable
3657
fun BottomSheet(
3758
isVisible: Boolean,
38-
bottomSheetContent: @Composable () -> Unit
59+
sheetTitle: String = "",
60+
onDismissRequest: () -> Unit = { },
61+
bottomSheetContent: @Composable (ColumnScope) -> Unit
3962
) {
4063
Box(
4164
modifier = Modifier.fillMaxSize()
4265
) {
4366
AnimatedVisibility(
4467
modifier = Modifier.align(Alignment.BottomCenter),
4568
visible = isVisible,
46-
enter = slideInVertically{height -> height} + fadeIn(),
47-
exit = slideOutVertically{height -> height} + fadeOut()
69+
enter = slideInVertically { height -> height } + fadeIn(),
70+
exit = slideOutVertically { height -> height } + fadeOut()
71+
) {
72+
SampleAppTheme {
73+
Surface {
74+
Column(
75+
verticalArrangement = Arrangement.spacedBy(8.dp),
76+
horizontalAlignment = Alignment.CenterHorizontally
77+
) {
78+
if (sheetTitle != "") {
79+
Row(
80+
modifier = Modifier
81+
.fillMaxWidth()
82+
.padding(12.dp),
83+
horizontalArrangement = Arrangement.SpaceBetween,
84+
verticalAlignment = Alignment.CenterVertically
85+
) {
86+
Text(
87+
text = sheetTitle,
88+
style = MaterialTheme.typography.titleLarge
89+
)
90+
FilledTonalIconButton(onClick = onDismissRequest) {
91+
Icon(Icons.Filled.Close, contentDescription = "CloseSheetIcon")
92+
}
93+
}
94+
}
95+
bottomSheetContent(this)
96+
Spacer(Modifier.height(12.dp))
97+
}
98+
}
99+
}
100+
}
101+
}
102+
}
103+
104+
@Preview(showBackground = true)
105+
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
106+
@Composable
107+
fun BottomSheetPreview() {
108+
val dropDownItems = listOf("Option #1", "Option #2", "Option #3")
109+
SamplePreviewSurface {
110+
BottomSheet(
111+
sheetTitle = "Bottom sheet options:",
112+
isVisible = true
48113
) {
49-
bottomSheetContent()
114+
DropDownMenuBox(
115+
textFieldValue = dropDownItems[0],
116+
textFieldLabel = "Select an option",
117+
dropDownItemList = dropDownItems,
118+
onIndexSelected = { }
119+
)
50120
}
51121
}
52122
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.sampleslib.components
18+
19+
import android.content.res.Configuration
20+
import androidx.compose.animation.animateContentSize
21+
import androidx.compose.foundation.background
22+
import androidx.compose.foundation.layout.Arrangement
23+
import androidx.compose.foundation.layout.Column
24+
import androidx.compose.foundation.layout.ColumnScope
25+
import androidx.compose.foundation.layout.Row
26+
import androidx.compose.foundation.layout.fillMaxWidth
27+
import androidx.compose.foundation.layout.padding
28+
import androidx.compose.foundation.rememberScrollState
29+
import androidx.compose.foundation.shape.RoundedCornerShape
30+
import androidx.compose.foundation.verticalScroll
31+
import androidx.compose.material3.MaterialTheme
32+
import androidx.compose.material3.OutlinedButton
33+
import androidx.compose.material3.Text
34+
import androidx.compose.runtime.Composable
35+
import androidx.compose.ui.Alignment
36+
import androidx.compose.ui.Modifier
37+
import androidx.compose.ui.draw.clip
38+
import androidx.compose.ui.tooling.preview.Preview
39+
import androidx.compose.ui.unit.dp
40+
import androidx.compose.ui.window.Dialog
41+
import androidx.compose.ui.window.DialogProperties
42+
43+
/**
44+
* Composable component to display a dialog of the [content], which provides an [onDismissRequest].
45+
* The [modifier] applies common dialog layout configurations using the default [properties].
46+
*/
47+
@Composable
48+
fun SampleDialog(
49+
modifier: Modifier = Modifier,
50+
properties: DialogProperties = DialogProperties(),
51+
onDismissRequest: () -> Unit,
52+
content: @Composable (ColumnScope) -> Unit
53+
) {
54+
Dialog(onDismissRequest = onDismissRequest, properties = properties) {
55+
Column(
56+
modifier = modifier
57+
.clip(RoundedCornerShape(12.dp))
58+
.background(MaterialTheme.colorScheme.background)
59+
.padding(12.dp)
60+
.fillMaxWidth()
61+
.verticalScroll(rememberScrollState())
62+
.animateContentSize(),
63+
verticalArrangement = Arrangement.spacedBy(8.dp),
64+
horizontalAlignment = Alignment.CenterHorizontally,
65+
) {
66+
content(this)
67+
}
68+
}
69+
}
70+
71+
@Preview(showBackground = true)
72+
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
73+
@Composable
74+
fun DialogOptionsPreview() {
75+
SamplePreviewSurface {
76+
SampleDialog(onDismissRequest = {}) {
77+
Text("Sample options: ", style = MaterialTheme.typography.titleMedium)
78+
DropDownMenuBox(
79+
textFieldValue = "Current selection",
80+
textFieldLabel = "Select an option",
81+
dropDownItemList = emptyList(),
82+
onIndexSelected = { }
83+
)
84+
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
85+
OutlinedButton(onClick = { }) { Text("Dismiss") }
86+
}
87+
}
88+
}
89+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.sampleslib.components
18+
19+
import androidx.compose.material3.Surface
20+
import androidx.compose.runtime.Composable
21+
import com.esri.arcgismaps.sample.sampleslib.theme.SampleAppTheme
22+
23+
/**
24+
* Helper composable to apply sample theme to the given [content] for previews.
25+
*/
26+
@Composable
27+
fun SamplePreviewSurface(content: @Composable () -> Unit) {
28+
SampleAppTheme {
29+
Surface { content() }
30+
}
31+
}

Diff for: tools/NewModuleScript.jar

-15.5 KB
Binary file not shown.
+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/* Copyright 2023 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.displaycomposablemapview.screens
18+
19+
import android.content.res.Configuration
20+
import androidx.compose.foundation.layout.Arrangement
21+
import androidx.compose.foundation.layout.Column
22+
import androidx.compose.foundation.layout.fillMaxSize
23+
import androidx.compose.foundation.layout.padding
24+
import androidx.compose.material.icons.Icons
25+
import androidx.compose.material.icons.filled.Settings
26+
import androidx.compose.material3.FloatingActionButton
27+
import androidx.compose.material3.Icon
28+
import androidx.compose.material3.Scaffold
29+
import androidx.compose.runtime.Composable
30+
import androidx.compose.runtime.getValue
31+
import androidx.compose.runtime.mutableStateOf
32+
import androidx.compose.runtime.remember
33+
import androidx.compose.runtime.setValue
34+
import androidx.compose.ui.Alignment
35+
import androidx.compose.ui.Modifier
36+
import androidx.compose.ui.tooling.preview.Preview
37+
import androidx.compose.ui.unit.dp
38+
import androidx.lifecycle.viewmodel.compose.viewModel
39+
import com.arcgismaps.toolkit.geoviewcompose.MapView
40+
import com.esri.arcgismaps.sample.displaycomposablemapview.components.MapViewModel
41+
import com.esri.arcgismaps.sample.sampleslib.components.BottomSheet
42+
import com.esri.arcgismaps.sample.sampleslib.components.DropDownMenuBox
43+
import com.esri.arcgismaps.sample.sampleslib.components.MessageDialog
44+
import com.esri.arcgismaps.sample.sampleslib.components.SamplePreviewSurface
45+
import com.esri.arcgismaps.sample.sampleslib.components.SampleTopAppBar
46+
47+
/**
48+
* Main screen layout for the sample app
49+
*/
50+
@Composable
51+
fun MainScreen(sampleName: String) {
52+
val mapViewModel: MapViewModel = viewModel()
53+
var isBottomSheetVisible by remember { mutableStateOf(false) }
54+
55+
Scaffold(
56+
topBar = { SampleTopAppBar(title = sampleName) },
57+
floatingActionButton = {
58+
if (!isBottomSheetVisible) {
59+
FloatingActionButton(
60+
modifier = Modifier.padding(bottom = 36.dp, end = 12.dp),
61+
onClick = { isBottomSheetVisible = true }
62+
) { Icon(Icons.Filled.Settings, contentDescription = "Show options") }
63+
}
64+
},
65+
content = {
66+
Column(
67+
modifier = Modifier
68+
.fillMaxSize()
69+
.padding(it),
70+
) {
71+
MapView(
72+
modifier = Modifier
73+
.fillMaxSize()
74+
.weight(1f),
75+
arcGISMap = mapViewModel.arcGISMap,
76+
onVisibleAreaChanged = { isBottomSheetVisible = false }
77+
)
78+
}
79+
80+
BottomSheet(
81+
isVisible = isBottomSheetVisible,
82+
sheetTitle = "Bottom sheet options",
83+
onDismissRequest = { isBottomSheetVisible = false }
84+
) {
85+
SampleOptions(
86+
// isCurrentOptionEnabled = ...,
87+
// onOptionToggled = { ... },
88+
)
89+
}
90+
91+
mapViewModel.messageDialogVM.apply {
92+
if (dialogStatus) {
93+
MessageDialog(
94+
title = messageTitle,
95+
description = messageDescription,
96+
onDismissRequest = ::dismissDialog
97+
)
98+
}
99+
}
100+
}
101+
)
102+
}
103+
104+
@Composable
105+
fun SampleOptions() {
106+
Column(
107+
verticalArrangement = Arrangement.spacedBy(8.dp),
108+
horizontalAlignment = Alignment.CenterHorizontally
109+
) {
110+
DropDownMenuBox(
111+
textFieldValue = "<selected-option>",
112+
textFieldLabel = "Select an option",
113+
dropDownItemList = emptyList(),
114+
onIndexSelected = { }
115+
)
116+
}
117+
}
118+
119+
@Preview(showBackground = true)
120+
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
121+
@Composable
122+
fun BottomSheetPreview() {
123+
SamplePreviewSurface {
124+
BottomSheet(
125+
isVisible = true,
126+
sheetTitle = "Bottom sheet options",
127+
) {
128+
SampleOptions()
129+
}
130+
}
131+
}

0 commit comments

Comments
 (0)