I started to learn Jetpack Compose and it looks confusing how to implement a simple snackbar, using material3 dependencies.
Scaffold(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }
) { padding ->
Box(
modifier = Modifier
.padding(padding)
.fillMaxSize()
) {
Column() {
Box(
modifier = Modifier
.weight(0.25f)
.fillMaxSize()
.background(GreyOne)
) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
TitleBox(
title = R.string.app_name,
description = R.string.app_description,
image = R.mipmap.ic_launcher,
imageDescription = R.string.app_name
)
}
Box(
modifier = Modifier
.fillMaxSize()
.padding(10.dp),
contentAlignment = Alignment.BottomCenter
) {
if (state.isLoading) {
CircularProgressIndicator(
color = Color.White
)
}
}
}
Box(
modifier = Modifier
.weight(0.75f)
.fillMaxSize()
.background(GreyDark)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 30.dp)
.align(Alignment.TopCenter),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(id = R.string.login_big),
color = Color.White,
fontSize = 32.sp,
fontFamily = Roboto,
fontStyle = FontStyle.Normal,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(
top = 30.dp,
)
)
Spacer(modifier = Modifier.height(20.dp))
StandartTextField(
text = viewModel.usernameText.value,
//text = state.email,
hint = stringResource(id = R.string.email),
onValueChange = {
viewModel.setUsernameText(it)
},
keyboardType = KeyboardType.Email
)
Spacer(modifier = Modifier.height(16.dp))
StandartTextField(
text = viewModel.passwordText.value,
// text = state.password,
hint = stringResource(id = R.string.password),
onValueChange = {
viewModel.setPasswordText(it)
},
keyboardType = KeyboardType.Password
)
Spacer(modifier = Modifier.height(16.dp))
Button(
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
shape = RoundedCornerShape(corner = CornerSize(2.dp)),
colors = ButtonDefaults.buttonColors(GreyOne),
onClick = { viewModel.login() }
) {
Text(
stringResource(id = R.string.login),
fontSize = 18.sp,
fontFamily = Roboto,
fontStyle = FontStyle.Normal,
fontWeight = FontWeight.Normal
)
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 30.dp)
.align(Alignment.BottomCenter),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(id = R.string.or_log_in_with),
color = GreyText,
fontSize = 16.sp
)
Spacer(modifier = Modifier.height(15.dp))
Button(
modifier = Modifier
.border(
BorderStroke(1.dp, color = GreyOne)
)
.width(180.dp),
onClick = { null },
colors = ButtonDefaults.buttonColors(Color.Transparent)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Image(
painterResource(id = R.drawable.icon_google),
contentDescription = stringResource(id = R.string.google),
contentScale = ContentScale.Fit,
modifier = Modifier.size(35.dp)
)
Spacer(modifier = Modifier.width(5.dp))
Text(
text = stringResource(id = R.string.google),
color = GreyText,
fontSize = 16.sp
)
}
}
Spacer(modifier = Modifier.height(50.dp))
Text(
text = stringResource(id = R.string.forgot),
color = Color.White,
fontSize = 16.sp,
)
Spacer(modifier = Modifier.height(20.dp))
Button(
colors = ButtonDefaults.buttonColors(Color.Transparent),
onClick = { null }
) {
Text(
text = stringResource(id = R.string.register),
fontSize = 15.sp,
fontFamily = Roboto,
color = Color.White
)
}
Spacer(modifier = Modifier.height(20.dp))
}
}
}
}
}
@Composable
fun StandartTextField(
text: String,
hint: String,
isError: Boolean = false,
keyboardType: KeyboardType = KeyboardType.Text,
onValueChange: (String) -> Unit
) {
val isPasswordToggleDisplayed by remember {
mutableStateOf(keyboardType == KeyboardType.Password)
}
var isPasswordVisible by remember {
mutableStateOf(false)
}
TextField(
value = text,
textStyle = TextStyle.Default.copy(
fontSize = 18.sp,
fontFamily = Roboto,
fontStyle = FontStyle.Normal,
fontWeight = FontWeight.Normal
),
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.Transparent,
textColor = Color.White,
focusedIndicatorColor = Color.White,
unfocusedIndicatorColor = GreyOne,
cursorColor = Color.White
),
onValueChange = onValueChange,
placeholder = {
Text(text = hint)
},
isError = isError,
keyboardOptions = KeyboardOptions(
keyboardType = keyboardType
),
visualTransformation = if (!isPasswordVisible && isPasswordToggleDisplayed) {
PasswordVisualTransformation()
} else {
VisualTransformation.None
},
singleLine = true,
trailingIcon = {
if (isPasswordToggleDisplayed) {
IconButton(onClick = {
isPasswordVisible = !isPasswordVisible
}) {
Icon(
imageVector = if (isPasswordVisible) {
Icons.Filled.VisibilityOff
} else {
Icons.Filled.Visibility
},
contentDescription = if (isPasswordVisible) {
stringResource(id = R.string.password_visible_content_description)
} else {
stringResource(id = R.string.password_hidden_content_description)
}
)
}
}
},
modifier = Modifier
.fillMaxWidth()
)
}
@Composable
fun TitleBox(
title: Int,
description: Int,
image: Int,
imageDescription: Int
) {
Row(
verticalAlignment = Alignment.CenterVertically
)
{
Image(
painter = painterResource(id = image),
contentDescription = stringResource(id = imageDescription)
)
Column {
Text(
text = stringResource(id = title),
color = Color.White,
fontSize = 28.sp,
fontFamily = Roboto,
fontStyle = FontStyle.Normal,
fontWeight = FontWeight.Bold
)
Text(
text = stringResource(id = description),
color = Color.White,
fontFamily = Roboto,
fontStyle = FontStyle.Normal,
fontWeight = FontWeight.Normal
)
}
}
}