I have made a length-units converter with Jetpack Compose.
Here's the source-code:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
LengthConverterTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
MainUI()
}
}
}
}
}
fun convertInput(fromUnit: Units, toUnit: Units, fromValue: Double): Double {
var lengthMeter = 0.0
when (fromUnit) {
Units.meter -> lengthMeter = fromValue * 1.0
Units.kilometer -> lengthMeter = fromValue * 1000.0
Units.feet -> lengthMeter = fromValue * 0.3048
Units.yard -> lengthMeter = fromValue * 0.9144
Units.miles -> lengthMeter = fromValue * 1609.34
}
var resultVal = 0.0
when (toUnit) {
Units.meter -> resultVal = lengthMeter
Units.kilometer -> resultVal = lengthMeter / 1000.0
Units.feet -> resultVal = lengthMeter * 3.28084
Units.yard -> resultVal = lengthMeter * 1.09361
Units.miles -> {
resultVal = lengthMeter * 0.000621371
}
}
return resultVal
}
@Composable
fun MainUI() {
val context = LocalContext.current
var isSelectedFrom by remember {
mutableStateOf(Units.meter)
}
var isSelectedTo by remember {
mutableStateOf(Units.meter)
}
var userInput by remember {
mutableStateOf("0.0")
}
var currentResult by remember {
mutableStateOf(0.0)
}
Column(modifier = Modifier
.fillMaxWidth()
.padding(
top = 15.dp,
start = 25.dp,
end = 25.dp
)) {
TextField(value = userInput,
modifier = Modifier
.fillMaxWidth()
.padding(top = 10.dp),
placeholder = {
Text("Enter value to convert")
},
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.White,
textColor = Color.Black),
onValueChange = {
if (it.isNotEmpty()) {
userInput = it
currentResult = convertInput(isSelectedFrom, isSelectedTo, it.toDouble())
}
})
UnitPicker(title = "Convert from: ",
currentlySelected = isSelectedFrom) {
isSelectedFrom = it
currentResult = convertInput(isSelectedFrom, isSelectedTo, userInput.toDouble())
}
UnitPicker(title = "Convert to: ",
currentlySelected = isSelectedTo) {
isSelectedTo = it
currentResult = convertInput(isSelectedFrom, isSelectedTo, userInput.toDouble())
}
Text("Result: ${currentResult.toString()}",
modifier = Modifier.padding(top = 25.dp),
fontSize = 20.sp,
fontWeight = FontWeight.Bold)
}
}
@Composable
fun UnitPicker(title: String, currentlySelected: Units, setUnit: (Units) -> Unit) {
Text("Convert from: ", fontSize = 20.sp, fontWeight = FontWeight.Bold)
Units.values().forEach {
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically) {
Text(it.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() })
var isSelected = it == currentlySelected
RadioButton(selected = isSelected,
onClick = {
setUnit(it)
})
}
}
Divider()
}
enum class Units {
meter,
kilometer,
feet,
yard,
miles
}
Could the central algorithm (within the function 'convertInput') become improved? Is there are more elegant solution?
What should me modified to accomplish a more Kotlin-ideomatic code?
Looking forward to reading your answers and comments?