Skip to content

Commit 36029ca

Browse files
authoredAug 30, 2022
[Jetsurvey] Converted to use Material 3 (android#954)
This updates Jetsurvey from Material 2 to Material 3. All Compose components now use Material 3 instead of Material 2. The date picker is currently still using the MaterialDatePicker DialogFragment the same as before this change. This also fixes the visibility of the status bars when in light mode and updates the screenshot and animated gif. Before: https://raw.githubusercontent.com/android/compose-samples/70d05efe9c5de6d3788ac3c6023caa20761d410a/Jetsurvey/screenshots/survey.gif After: https://raw.githubusercontent.com/android/compose-samples/ede93fc907ad32c61bd7f3d55a33af48e782ea2a/Jetsurvey/screenshots/survey.gif Co-authored-by: Ian G. Clifton <IanGClifton@users.noreply.github.com>
1 parent 76655dc commit 36029ca

File tree

21 files changed

+502
-387
lines changed

21 files changed

+502
-387
lines changed
 

Diff for: ‎Jetsurvey/app/build.gradle.kts

+2-1
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,15 @@ dependencies {
7575
implementation(libs.google.android.material)
7676

7777
implementation(libs.androidx.compose.foundation.layout)
78-
implementation(libs.androidx.compose.material)
78+
implementation(libs.androidx.compose.material3)
7979
implementation(libs.androidx.compose.material.iconsExtended)
8080
implementation(libs.androidx.compose.ui.tooling.preview)
8181
implementation(libs.androidx.compose.runtime)
8282
implementation(libs.androidx.compose.runtime.livedata)
8383
debugImplementation(libs.androidx.compose.ui.tooling)
8484

8585
implementation(libs.accompanist.permissions)
86+
implementation(libs.accompanist.systemuicontroller)
8687

8788
implementation(libs.coil.kt.compose)
8889

Diff for: ‎Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInScreen.kt

+18-25
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.example.compose.jetsurvey.signinsignup
1818

19+
import android.content.res.Configuration.UI_MODE_NIGHT_NO
20+
import android.content.res.Configuration.UI_MODE_NIGHT_YES
1921
import androidx.compose.foundation.layout.Box
2022
import androidx.compose.foundation.layout.Column
2123
import androidx.compose.foundation.layout.Spacer
@@ -24,15 +26,15 @@ import androidx.compose.foundation.layout.fillMaxWidth
2426
import androidx.compose.foundation.layout.height
2527
import androidx.compose.foundation.layout.padding
2628
import androidx.compose.foundation.layout.wrapContentHeight
27-
import androidx.compose.material.Button
28-
import androidx.compose.material.ExperimentalMaterialApi
29-
import androidx.compose.material.MaterialTheme
30-
import androidx.compose.material.Scaffold
31-
import androidx.compose.material.Snackbar
32-
import androidx.compose.material.SnackbarHost
33-
import androidx.compose.material.SnackbarHostState
34-
import androidx.compose.material.Text
35-
import androidx.compose.material.TextButton
29+
import androidx.compose.material3.Button
30+
import androidx.compose.material3.ExperimentalMaterial3Api
31+
import androidx.compose.material3.MaterialTheme
32+
import androidx.compose.material3.Scaffold
33+
import androidx.compose.material3.Snackbar
34+
import androidx.compose.material3.SnackbarHost
35+
import androidx.compose.material3.SnackbarHostState
36+
import androidx.compose.material3.Text
37+
import androidx.compose.material3.TextButton
3638
import androidx.compose.runtime.Composable
3739
import androidx.compose.runtime.getValue
3840
import androidx.compose.runtime.mutableStateOf
@@ -48,7 +50,6 @@ import androidx.compose.ui.tooling.preview.Preview
4850
import androidx.compose.ui.unit.dp
4951
import com.example.compose.jetsurvey.R
5052
import com.example.compose.jetsurvey.theme.JetsurveyTheme
51-
import com.example.compose.jetsurvey.theme.snackbarAction
5253
import com.example.compose.jetsurvey.util.supportWideScreen
5354
import kotlinx.coroutines.launch
5455

@@ -59,7 +60,7 @@ sealed class SignInEvent {
5960
object NavigateBack : SignInEvent()
6061
}
6162

62-
@OptIn(ExperimentalMaterialApi::class)
63+
@OptIn(ExperimentalMaterial3Api::class) // Scaffold is experimental in m3
6364
@Composable
6465
fun SignIn(onNavigationEvent: (SignInEvent) -> Unit) {
6566

@@ -157,7 +158,6 @@ fun SignInContent(
157158
}
158159
}
159160

160-
@OptIn(ExperimentalMaterialApi::class)
161161
@Composable
162162
fun ErrorSnackbar(
163163
snackbarHostState: SnackbarHostState,
@@ -171,16 +171,16 @@ fun ErrorSnackbar(
171171
modifier = Modifier.padding(16.dp),
172172
content = {
173173
Text(
174-
text = data.message,
175-
style = MaterialTheme.typography.body2
174+
text = data.visuals.message,
175+
style = MaterialTheme.typography.bodyMedium,
176176
)
177177
},
178178
action = {
179-
data.actionLabel?.let {
179+
data.visuals.actionLabel?.let {
180180
TextButton(onClick = onDismiss) {
181181
Text(
182182
text = stringResource(id = R.string.dismiss),
183-
color = MaterialTheme.colors.snackbarAction
183+
color = MaterialTheme.colorScheme.inversePrimary
184184
)
185185
}
186186
}
@@ -193,18 +193,11 @@ fun ErrorSnackbar(
193193
)
194194
}
195195

196-
@Preview(name = "Sign in light theme")
196+
@Preview(name = "Sign in light theme", uiMode = UI_MODE_NIGHT_NO)
197+
@Preview(name = "Sign in dark theme", uiMode = UI_MODE_NIGHT_YES)
197198
@Composable
198199
fun SignInPreview() {
199200
JetsurveyTheme {
200201
SignIn {}
201202
}
202203
}
203-
204-
@Preview(name = "Sign in dark theme")
205-
@Composable
206-
fun SignInPreviewDark() {
207-
JetsurveyTheme(darkTheme = true) {
208-
SignIn {}
209-
}
210-
}

Diff for: ‎Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInSignUp.kt

+46-51
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,20 @@ import androidx.compose.foundation.layout.wrapContentSize
3131
import androidx.compose.foundation.lazy.LazyColumn
3232
import androidx.compose.foundation.text.KeyboardActions
3333
import androidx.compose.foundation.text.KeyboardOptions
34-
import androidx.compose.material.ContentAlpha
35-
import androidx.compose.material.Icon
36-
import androidx.compose.material.IconButton
37-
import androidx.compose.material.LocalContentAlpha
38-
import androidx.compose.material.LocalTextStyle
39-
import androidx.compose.material.MaterialTheme
40-
import androidx.compose.material.OutlinedButton
41-
import androidx.compose.material.OutlinedTextField
42-
import androidx.compose.material.Surface
43-
import androidx.compose.material.Text
44-
import androidx.compose.material.TextField
45-
import androidx.compose.material.TopAppBar
4634
import androidx.compose.material.icons.Icons
4735
import androidx.compose.material.icons.filled.ChevronLeft
4836
import androidx.compose.material.icons.filled.Visibility
4937
import androidx.compose.material.icons.filled.VisibilityOff
38+
import androidx.compose.material3.CenterAlignedTopAppBar
39+
import androidx.compose.material3.ExperimentalMaterial3Api
40+
import androidx.compose.material3.Icon
41+
import androidx.compose.material3.IconButton
42+
import androidx.compose.material3.MaterialTheme
43+
import androidx.compose.material3.OutlinedButton
44+
import androidx.compose.material3.OutlinedTextField
45+
import androidx.compose.material3.Surface
46+
import androidx.compose.material3.Text
5047
import androidx.compose.runtime.Composable
51-
import androidx.compose.runtime.CompositionLocalProvider
5248
import androidx.compose.runtime.mutableStateOf
5349
import androidx.compose.runtime.remember
5450
import androidx.compose.runtime.saveable.rememberSaveable
@@ -60,17 +56,18 @@ import androidx.compose.ui.text.input.ImeAction
6056
import androidx.compose.ui.text.input.KeyboardType
6157
import androidx.compose.ui.text.input.PasswordVisualTransformation
6258
import androidx.compose.ui.text.input.VisualTransformation
63-
import androidx.compose.ui.text.style.TextAlign
6459
import androidx.compose.ui.tooling.preview.Preview
6560
import androidx.compose.ui.unit.dp
6661
import com.example.compose.jetsurvey.R
62+
import com.example.compose.jetsurvey.theme.JetsurveyTheme
63+
import com.example.compose.jetsurvey.theme.stronglyDeemphasizedAlpha
6764

6865
@Composable
6966
fun SignInSignUpScreen(
7067
onSignedInAsGuest: () -> Unit,
7168
modifier: Modifier = Modifier,
7269
contentPadding: PaddingValues = PaddingValues(),
73-
content: @Composable() () -> Unit
70+
content: @Composable () -> Unit
7471
) {
7572
LazyColumn(
7673
modifier = modifier,
@@ -96,13 +93,13 @@ fun SignInSignUpScreen(
9693
}
9794
}
9895

96+
@OptIn(ExperimentalMaterial3Api::class) // CenterAlignedTopAppBar is experimental in m3
9997
@Composable
10098
fun SignInSignUpTopAppBar(topAppBarText: String, onBackPressed: () -> Unit) {
101-
TopAppBar(
99+
CenterAlignedTopAppBar(
102100
title = {
103101
Text(
104102
text = topAppBarText,
105-
textAlign = TextAlign.Center,
106103
modifier = Modifier
107104
.fillMaxSize()
108105
.wrapContentSize(Alignment.Center)
@@ -112,19 +109,19 @@ fun SignInSignUpTopAppBar(topAppBarText: String, onBackPressed: () -> Unit) {
112109
IconButton(onClick = onBackPressed) {
113110
Icon(
114111
imageVector = Icons.Filled.ChevronLeft,
115-
contentDescription = stringResource(id = R.string.back)
112+
contentDescription = stringResource(id = R.string.back),
113+
tint = MaterialTheme.colorScheme.primary
116114
)
117115
}
118116
},
119117
// We need to balance the navigation icon, so we add a spacer.
120118
actions = {
121119
Spacer(modifier = Modifier.width(68.dp))
122120
},
123-
backgroundColor = MaterialTheme.colors.surface,
124-
elevation = 0.dp
125121
)
126122
}
127123

124+
@OptIn(ExperimentalMaterial3Api::class) // OutlinedTextField is experimental in m3
128125
@Composable
129126
fun Email(
130127
emailState: TextFieldState = remember { EmailState() },
@@ -137,12 +134,10 @@ fun Email(
137134
emailState.text = it
138135
},
139136
label = {
140-
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
141-
Text(
142-
text = stringResource(id = R.string.email),
143-
style = MaterialTheme.typography.body2
144-
)
145-
}
137+
Text(
138+
text = stringResource(id = R.string.email),
139+
style = MaterialTheme.typography.bodyMedium,
140+
)
146141
},
147142
modifier = Modifier
148143
.fillMaxWidth()
@@ -152,7 +147,7 @@ fun Email(
152147
emailState.enableShowErrors()
153148
}
154149
},
155-
textStyle = MaterialTheme.typography.body2,
150+
textStyle = MaterialTheme.typography.bodyMedium,
156151
isError = emailState.showErrors(),
157152
keyboardOptions = KeyboardOptions.Default.copy(
158153
imeAction = imeAction,
@@ -162,12 +157,13 @@ fun Email(
162157
onDone = {
163158
onImeAction()
164159
}
165-
)
160+
),
166161
)
167162

168163
emailState.getError()?.let { error -> TextFieldError(textError = error) }
169164
}
170165

166+
@OptIn(ExperimentalMaterial3Api::class) // OutlinedTextField is experimental in m3
171167
@Composable
172168
fun Password(
173169
label: String,
@@ -191,14 +187,12 @@ fun Password(
191187
passwordState.enableShowErrors()
192188
}
193189
},
194-
textStyle = MaterialTheme.typography.body2,
190+
textStyle = MaterialTheme.typography.bodyMedium,
195191
label = {
196-
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
197-
Text(
198-
text = label,
199-
style = MaterialTheme.typography.body2
200-
)
201-
}
192+
Text(
193+
text = label,
194+
style = MaterialTheme.typography.bodyMedium,
195+
)
202196
},
203197
trailingIcon = {
204198
if (showPassword.value) {
@@ -231,7 +225,7 @@ fun Password(
231225
onDone = {
232226
onImeAction()
233227
}
234-
)
228+
),
235229
)
236230

237231
passwordState.getError()?.let { error -> TextFieldError(textError = error) }
@@ -247,7 +241,7 @@ fun TextFieldError(textError: String) {
247241
Text(
248242
text = textError,
249243
modifier = Modifier.fillMaxWidth(),
250-
style = LocalTextStyle.current.copy(color = MaterialTheme.colors.error)
244+
color = MaterialTheme.colorScheme.error
251245
)
252246
}
253247
}
@@ -261,20 +255,17 @@ fun OrSignInAsGuest(
261255
modifier = modifier,
262256
horizontalAlignment = Alignment.CenterHorizontally
263257
) {
264-
Surface {
265-
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
266-
Text(
267-
text = stringResource(id = R.string.or),
268-
style = MaterialTheme.typography.subtitle2,
269-
modifier = Modifier.paddingFromBaseline(top = 25.dp)
270-
)
271-
}
272-
}
258+
Text(
259+
text = stringResource(id = R.string.or),
260+
style = MaterialTheme.typography.titleSmall,
261+
color = MaterialTheme.colorScheme.onSurface.copy(alpha = stronglyDeemphasizedAlpha),
262+
modifier = Modifier.paddingFromBaseline(top = 25.dp)
263+
)
273264
OutlinedButton(
274265
onClick = onSignedInAsGuest,
275266
modifier = Modifier
276267
.fillMaxWidth()
277-
.padding(top = 20.dp, bottom = 24.dp)
268+
.padding(top = 20.dp, bottom = 24.dp),
278269
) {
279270
Text(text = stringResource(id = R.string.sign_in_guest))
280271
}
@@ -284,8 +275,12 @@ fun OrSignInAsGuest(
284275
@Preview
285276
@Composable
286277
fun SignInSignUpScreenPreview() {
287-
SignInSignUpScreen(
288-
onSignedInAsGuest = {},
289-
content = {}
290-
)
278+
JetsurveyTheme {
279+
Surface {
280+
SignInSignUpScreen(
281+
onSignedInAsGuest = {},
282+
content = {}
283+
)
284+
}
285+
}
291286
}

Diff for: ‎Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignUpScreen.kt

+12-13
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,12 @@ import androidx.compose.foundation.layout.Column
2020
import androidx.compose.foundation.layout.Spacer
2121
import androidx.compose.foundation.layout.fillMaxWidth
2222
import androidx.compose.foundation.layout.height
23-
import androidx.compose.material.Button
24-
import androidx.compose.material.ContentAlpha
25-
import androidx.compose.material.LocalContentAlpha
26-
import androidx.compose.material.MaterialTheme
27-
import androidx.compose.material.Scaffold
28-
import androidx.compose.material.Text
23+
import androidx.compose.material3.Button
24+
import androidx.compose.material3.ExperimentalMaterial3Api
25+
import androidx.compose.material3.MaterialTheme
26+
import androidx.compose.material3.Scaffold
27+
import androidx.compose.material3.Text
2928
import androidx.compose.runtime.Composable
30-
import androidx.compose.runtime.CompositionLocalProvider
3129
import androidx.compose.runtime.remember
3230
import androidx.compose.ui.Modifier
3331
import androidx.compose.ui.focus.FocusRequester
@@ -38,6 +36,7 @@ import androidx.compose.ui.tooling.preview.Preview
3836
import androidx.compose.ui.unit.dp
3937
import com.example.compose.jetsurvey.R
4038
import com.example.compose.jetsurvey.theme.JetsurveyTheme
39+
import com.example.compose.jetsurvey.theme.stronglyDeemphasizedAlpha
4140
import com.example.compose.jetsurvey.util.supportWideScreen
4241

4342
sealed class SignUpEvent {
@@ -47,6 +46,7 @@ sealed class SignUpEvent {
4746
object NavigateBack : SignUpEvent()
4847
}
4948

49+
@OptIn(ExperimentalMaterial3Api::class) // Scaffold is experimental in m3
5050
@Composable
5151
fun SignUp(onNavigationEvent: (SignUpEvent) -> Unit) {
5252
Scaffold(
@@ -104,12 +104,11 @@ fun SignUpContent(
104104
)
105105

106106
Spacer(modifier = Modifier.height(16.dp))
107-
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
108-
Text(
109-
text = stringResource(id = R.string.terms_and_conditions),
110-
style = MaterialTheme.typography.caption
111-
)
112-
}
107+
Text(
108+
text = stringResource(id = R.string.terms_and_conditions),
109+
style = MaterialTheme.typography.bodySmall,
110+
color = MaterialTheme.colorScheme.onSurface.copy(alpha = stronglyDeemphasizedAlpha)
111+
)
113112

114113
Spacer(modifier = Modifier.height(16.dp))
115114
Button(

0 commit comments

Comments
 (0)
Please sign in to comment.