Skip to content

Instantly share code, notes, and snippets.

@kafri8889
Created June 29, 2022 05:10
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kafri8889/febb725b668812dac6338224ada9e05b to your computer and use it in GitHub Desktop.
Save kafri8889/febb725b668812dac6338224ada9e05b to your computer and use it in GitHub Desktop.
@Composable
fun SettingPreference(
preference: Preference,
onClick: (Any) -> Unit
) {
when (preference) {
is BasicPreference -> {
BasicPreference(
preference = preference,
onClick = onClick
)
}
is SwitchPreference -> {
SwitchPreference(
preference = preference,
onClick = onClick
)
}
}
}
@Composable
fun SettingPreferences(
preferences: List<Preference>,
modifier: Modifier = Modifier,
onClick: (Preference) -> Unit
) {
val groupedPreference = preferences.groupBy { it.category }
groupedPreference.forEach {
Column(
modifier = Modifier
.fillMaxWidth()
.then(modifier)
) {
Text(
text = it.key,
style = Typography.titleMedium.copy(
color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Bold,
),
modifier = Modifier
.padding(
top = 16.dp,
bottom = 8.dp,
start = 12.dp,
end = 12.dp
)
)
it.value.forEach { preference ->
SettingPreference(
preference = preference,
onClick = {
onClick(
when (preference) {
is BasicPreference -> preference.copy(value = it)
is SwitchPreference -> preference.copy(isChecked = it as Boolean)
}
)
}
)
}
}
}
}
@Composable
internal fun BasicPreference(
preference: BasicPreference,
onClick: (Any) -> Unit
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
.clickable { onClick("") }
) {
if (preference.iconResId != null) {
Icon(
painter = painterResource(id = preference.iconResId),
contentDescription = null,
modifier = Modifier
.size(24.dp)
.weight(
weight = 0.12f
)
)
} else {
Box(
modifier = Modifier
.weight(weight = 0.12f)
)
}
Column(
verticalArrangement = Arrangement.Center,
modifier = Modifier
.weight(
weight = 0.6f
)
) {
Text(
text = preference.title,
style = Typography.titleMedium.copy(
fontWeight = FontWeight.Medium,
)
)
if (preference.summary.isNotBlank()) {
Text(
text = preference.summary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = Typography.titleSmall.copy(
color = Color.Gray,
fontWeight = FontWeight.Normal
)
)
}
}
Box(
contentAlignment = Alignment.CenterEnd,
modifier = Modifier
.padding(end = 12.dp)
.weight(0.28f)
) {
if (preference.showValue) {
Text(
text = preference.value.toString(),
textAlign = TextAlign.End,
style = Typography.titleMedium.copy(
fontSize = 15.sp,
fontWeight = FontWeight.Normal,
color = MaterialTheme.colorScheme.primary
)
)
}
}
}
}
@Composable
internal fun SwitchPreference(
preference: SwitchPreference,
onClick: (Any) -> Unit
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
.clickable {
onClick(!preference.isChecked)
}
) {
if (preference.iconResId != null) {
Icon(
painter = painterResource(id = preference.iconResId),
contentDescription = null,
modifier = Modifier
.size(24.dp)
.weight(0.12f)
)
} else {
Box(
modifier = Modifier
.weight(weight = 0.12f)
)
}
Column(
verticalArrangement = Arrangement.Center,
modifier = Modifier
.weight(0.6f)
) {
Text(
text = preference.title,
style = Typography.titleMedium.copy(
fontWeight = FontWeight.Medium,
)
)
if (preference.summary.isNotBlank()) {
Text(
text = preference.summary,
style = Typography.titleSmall.copy(
color = Color.Gray,
fontWeight = FontWeight.Normal
)
)
}
}
Switch(
checked = preference.isChecked,
onCheckedChange = {
onClick(!preference.isChecked)
},
modifier = Modifier
.weight(0.28f)
)
}
}
sealed interface Preference {
val title: String
val summary: String
val category: String
val iconResId: Int?
}
data class BasicPreference(
override val title: String,
override val summary: String,
override val category: String = "",
override val iconResId: Int? = null,
var value: Any = "",
var showValue: Boolean = false
): Preference
data class SwitchPreference(
override val title: String,
override val summary: String,
override val category: String = "",
override val iconResId: Int? = null,
var isChecked: Boolean,
): Preference
// Sample
@Composable
fun Screen() {
val settingPreferences = listOf(
BasicPreference(
title = stringResource(id = R.string.category),
summary = stringResource(id = R.string.category_summary),
iconResId = R.drawable.ic_category_2,
value = "",
category = stringResource(id = R.string.display_and_configuration)
),
BasicPreference(
title = "Show value",
summary = "",
iconResId = null,
value = "value",
showValue = true,
category = stringResource(id = R.string.display_and_configuration)
),
BasicPreference(
title = "Only title",
summary = "",
iconResId = null,
value = "",
showValue = false,
category = stringResource(id = R.string.display_and_configuration)
),
BasicPreference(
title = stringResource(id = R.string.language),
summary = stringResource(id = R.string.language_summary),
iconResId = R.drawable.ic_language,
value = "",
category = stringResource(id = R.string.display_and_configuration)
),
SwitchPreference(
title = stringResource(id = R.string.dark_theme),
summary = "",
iconResId = if (uiMode.isDarkTheme()) R.drawable.ic_moon else R.drawable.ic_sun,
isChecked = uiMode.isDarkTheme(),
category = stringResource(id = R.string.display_and_configuration),
),
SwitchPreference(
title = stringResource(id = R.string.biometric_authentication),
summary = stringResource(id = R.string.biometric_authentication_summary),
iconResId = R.drawable.ic_finger_scan,
isChecked = isUseBioAuth,
category = stringResource(id = R.string.security),
),
BasicPreference(
title = stringResource(id = R.string.export),
summary = "",
iconResId = R.drawable.ic_export,
category = stringResource(id = R.string.other),
)
)
SettingPreferences(
preferences = settingPreferences,
onClick = { preference ->
val selectedPreferenceIndex = settingPreferences.indexOf {
it.title == preference.title
}
when (selectedPreferenceIndex) {
0 -> {}
1 -> {}
2 -> {}
3 -> {}
4 -> uiModeViewModel.dispatch(
UiModeAction.SetUiMode(
if ((preference as SwitchPreference).isChecked) UiMode.DARK
else UiMode.LIGHT
)
)
}
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment