Implemented auto-capitalization toggle in AddBattery.kt.

Fixed case-sensitive sorting when retrieving batteries
Fixed behaviour of MyOutlinedTextFieldWithSuffix that always used up all the space.
This commit is contained in:
sockenklaus
2022-07-23 16:39:45 +02:00
parent ebbee65330
commit 3b2e09c134
7 changed files with 113 additions and 161 deletions

View File

@@ -16,7 +16,7 @@ interface BatteryDao {
@Update @Update
fun updateBattery(battery: Battery): Int fun updateBattery(battery: Battery): Int
@Query("Select * FROM batteries ORDER BY name ASC") @Query("Select * FROM batteries ORDER BY name COLLATE NOCASE ASC")
fun getBatteries(): Flow<List<Battery>> fun getBatteries(): Flow<List<Battery>>
@Query("Select * FROM batteries WHERE id = :id") @Query("Select * FROM batteries WHERE id = :id")

View File

@@ -53,7 +53,7 @@ fun BatteryTracker() {
) )
} }
} }
) { _ -> ) {
ModalDrawer( ModalDrawer(
drawerState = state.scaffoldState.drawerState, drawerState = state.scaffoldState.drawerState,
drawerContent = { drawerContent = {

View File

@@ -10,7 +10,9 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
@@ -19,6 +21,7 @@ import com.sockenklaus.batterytracker.ui.Routes
import com.sockenklaus.batterytracker.ui.composables.util.MyOutlinedTextFieldWithSuffix import com.sockenklaus.batterytracker.ui.composables.util.MyOutlinedTextFieldWithSuffix
import com.sockenklaus.batterytracker.ui.models.AddBatteryViewModel import com.sockenklaus.batterytracker.ui.models.AddBatteryViewModel
import com.sockenklaus.batterytracker.util.validateDecimal import com.sockenklaus.batterytracker.util.validateDecimal
import java.util.*
@Composable @Composable
fun AddBattery(navController: NavController){ fun AddBattery(navController: NavController){
@@ -32,22 +35,46 @@ fun AddBattery(navController: NavController){
Modifier.padding(outerPadding) Modifier.padding(outerPadding)
) { ) {
MyOutlinedTextFieldWithSuffix( Row(
value = model.batteryName, modifier = Modifier.fillMaxWidth(),
onValueChange = { value -> horizontalArrangement = Arrangement.SpaceBetween,
model.batteryName = value ){
model.batteryHasError = false
model.batteryHelperId = R.string.helper_required MyOutlinedTextFieldWithSuffix(
if(batteries.any{ it.name.equals(value, ignoreCase = true) }){ value = model.batteryName,
model.batteryHasError = true onValueChange = { value ->
model.batteryHelperId = R.string.helper_battery_not_unique model.batteryName = value
} model.batteryHasError = false
}, model.batteryHelperId = R.string.helper_required
labelId = R.string.hint_enter_battery_name, if(batteries.any{ it.name.equals(value, ignoreCase = true) }){
leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") }, model.batteryHasError = true
isError = model.batteryHasError, model.batteryHelperId = R.string.helper_battery_not_unique
helperTextId = model.batteryHelperId }
) },
labelId = R.string.hint_enter_battery_name,
leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") },
isError = model.batteryHasError,
helperTextId = model.batteryHelperId,
keyboardOptions = KeyboardOptions(
capitalization = if(model.switchAutoCap) KeyboardCapitalization.Characters else KeyboardCapitalization.None,
autoCorrect = false,
keyboardType = KeyboardType.Ascii
)
)
Column() {
Switch(
checked = model.switchAutoCap,
onCheckedChange = { model.switchAutoCap = !model.switchAutoCap }
)
Text(
text = "Auto-Cap.",
style = MaterialTheme.typography.caption
)
}
}
Spacer(Modifier.size(innerPadding)) Spacer(Modifier.size(innerPadding))
@@ -59,7 +86,8 @@ fun AddBattery(navController: NavController){
labelId = R.string.hint_enter_declared_capacity, labelId = R.string.hint_enter_declared_capacity,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
leadingIcon = { Icon(Icons.Default.BatteryFull, "Icon Battery Full") }, leadingIcon = { Icon(Icons.Default.BatteryFull, "Icon Battery Full") },
suffix = "Ah" suffix = "Ah",
modifier = Modifier.fillMaxWidth()
) )
Spacer(Modifier.size(outerPadding)) Spacer(Modifier.size(outerPadding))

View File

@@ -110,7 +110,8 @@ fun AddCharge(navController: NavController){
leadingIcon = { Icon(Icons.Default.BatteryChargingFull, "Icon Battery Charging Full") }, leadingIcon = { Icon(Icons.Default.BatteryChargingFull, "Icon Battery Charging Full") },
isError = model.chargeHasError, isError = model.chargeHasError,
helperTextId = R.string.helper_required, helperTextId = R.string.helper_required,
suffix = "Ah" suffix = "Ah",
modifier = Modifier.fillMaxWidth(),
) )
Spacer(Modifier.size(innerPadding)) Spacer(Modifier.size(innerPadding))

View File

@@ -30,7 +30,9 @@ fun Home(
val filteredList = batteries.filter { it.name.contains(filterText, ignoreCase = true) } val filteredList = batteries.filter { it.name.contains(filterText, ignoreCase = true) }
Column { Column(
modifier = Modifier.padding(bottom = 16.dp)
) {
MyOutlinedTextFieldWithSuffix( MyOutlinedTextFieldWithSuffix(
value = filterText, value = filterText,
onValueChange = { filterText = it }, onValueChange = { filterText = it },
@@ -40,6 +42,7 @@ fun Home(
start = 16.dp, start = 16.dp,
end = 16.dp end = 16.dp
) )
.fillMaxWidth()
) )
LazyColumn( LazyColumn(

View File

@@ -21,90 +21,6 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.sockenklaus.batterytracker.ui.theme.Gray500 import com.sockenklaus.batterytracker.ui.theme.Gray500
/*@Composable
fun TopAppBar(
title: @Composable () -> Unit,
modifier: Modifier = Modifier,
navigationIcon: @Composable (() -> Unit)? = null,
actions: @Composable RowScope.() -> Unit = {},
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = AppBarDefaults.TopAppBarElevation
) {
AppBar(
backgroundColor,
contentColor,
elevation,
AppBarDefaults.ContentPadding,
RectangleShape,
modifier
) {
if (navigationIcon == null) {
Spacer(Modifier.width(16.dp - 4.dp))
} else {
Row(Modifier.fillMaxHeight().width(72.dp - 4.dp), verticalAlignment = Alignment.CenterVertically) {
CompositionLocalProvider(
LocalContentAlpha provides ContentAlpha.high,
content = navigationIcon
)
}
}
Row(
Modifier.fillMaxHeight().weight(1f),
verticalAlignment = Alignment.CenterVertically
) {
ProvideTextStyle(value = MaterialTheme.typography.h6) {
CompositionLocalProvider(
LocalContentAlpha provides ContentAlpha.high,
content = title
)
}
}
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Row(
Modifier.fillMaxHeight(),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
content = actions
)
}
}
}
@Composable
private fun AppBar(
backgroundColor: Color,
contentColor: Color,
elevation: Dp,
contentPadding: PaddingValues,
shape: Shape,
modifier: Modifier = Modifier,
content: @Composable RowScope.() -> Unit
) {
Surface(
color = backgroundColor,
contentColor = contentColor,
elevation = elevation,
shape = shape,
modifier = modifier
) {
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Row(
Modifier.fillMaxWidth()
.padding(contentPadding)
.height(56.dp),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically,
content = content
)
}
}
}*/
@Composable @Composable
@OptIn(ExperimentalMaterialApi::class) @OptIn(ExperimentalMaterialApi::class)
fun MyOutlinedTextFieldWithSuffix( fun MyOutlinedTextFieldWithSuffix(
@@ -142,69 +58,72 @@ fun MyOutlinedTextFieldWithSuffix(
Gray500 Gray500
} }
BasicTextField( Column() {
value = value, BasicTextField(
modifier = modifier value = value,
modifier = modifier
.padding(top = 8.dp) .padding(top = 8.dp)
.background(colors.backgroundColor(enabled).value, shape) .background(colors.backgroundColor(enabled).value, shape)
.defaultMinSize( .defaultMinSize(
minWidth = TextFieldDefaults.MinWidth, minWidth = TextFieldDefaults.MinWidth,
minHeight = TextFieldDefaults.MinHeight minHeight = TextFieldDefaults.MinHeight
), ),
onValueChange = onValueChange, onValueChange = onValueChange,
enabled = enabled, enabled = enabled,
readOnly = readOnly, readOnly = readOnly,
textStyle = mergedTextStyle, textStyle = mergedTextStyle,
cursorBrush = SolidColor(colors.cursorColor(isError).value), cursorBrush = SolidColor(colors.cursorColor(isError).value),
visualTransformation = visualTransformation, visualTransformation = visualTransformation,
keyboardOptions = keyboardOptions, keyboardOptions = keyboardOptions,
keyboardActions = keyboardActions, keyboardActions = keyboardActions,
interactionSource = interactionSource, interactionSource = interactionSource,
singleLine = singleLine, singleLine = singleLine,
maxLines = maxLines, maxLines = maxLines,
decorationBox = @Composable { innerTextField -> decorationBox = @Composable { innerTextField ->
OutlinedTextFieldDecorationBox( OutlinedTextFieldDecorationBox(
value = value, value = value,
visualTransformation = visualTransformation, visualTransformation = visualTransformation,
innerTextField = { innerTextField = {
Row { Row(
val alignModifier = Modifier.alignByBaseline() horizontalArrangement = Arrangement.SpaceBetween
Box(alignModifier.weight(1f)){ ) {
innerTextField() val alignModifier = Modifier.alignByBaseline()
Box(alignModifier){
innerTextField()
}
Text(
suffix,
alignModifier,
colors.trailingIconColor(enabled = enabled, isError = isError).value
)
} }
Text( },
suffix, placeholder = placeholder,
alignModifier, label = { Text(stringResource(labelId)) },
colors.trailingIconColor(enabled = enabled, isError = isError).value leadingIcon = leadingIcon,
trailingIcon = trailingIcon,
singleLine = singleLine,
enabled = enabled,
isError = isError,
interactionSource = interactionSource,
colors = colors,
border = {
TextFieldDefaults.BorderBox(
enabled,
isError,
interactionSource,
colors,
shape
) )
} }
}, )
placeholder = placeholder, }
label = { Text(stringResource(labelId)) }, )
leadingIcon = leadingIcon, Text(
trailingIcon = trailingIcon, text = if(helperTextId != null) stringResource(helperTextId) else "",
singleLine = singleLine, style = MaterialTheme.typography.caption,
enabled = enabled, color = helperTextColor,
isError = isError, modifier = Modifier.padding(start = 16.dp)
interactionSource = interactionSource, )
colors = colors, }
border = {
TextFieldDefaults.BorderBox(
enabled,
isError,
interactionSource,
colors,
shape
)
}
)
}
)
Text(
text = if(helperTextId != null) stringResource(helperTextId) else "",
style = MaterialTheme.typography.caption,
color = helperTextColor,
modifier = Modifier.padding(start = 16.dp)
)
} }

View File

@@ -22,6 +22,7 @@ class AddBatteryViewModel(application: Application): AndroidViewModel(applicatio
var batteryName by mutableStateOf("") var batteryName by mutableStateOf("")
var batteryHasError by mutableStateOf(false) var batteryHasError by mutableStateOf(false)
var batteryHelperId by mutableStateOf(R.string.helper_required) var batteryHelperId by mutableStateOf(R.string.helper_required)
var switchAutoCap by mutableStateOf(true)
var declaredCapacity by mutableStateOf("") var declaredCapacity by mutableStateOf("")