Код: Выделить всё
@Query("SELECT DISTINCT make FROM ${DbSchema.MakeModelSchema.TABLE_NAME}")
fun observeDistinctMakes(): Flow
@Query("SELECT DISTINCT model FROM ${DbSchema.MakeModelSchema.TABLE_NAME} WHERE make = :make")
fun observeModelsByMake(make: String): Flow
Код: Выделить всё
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ModelSelection(
vinDescriptionFlow: MutableStateFlow,
previousMake: MutableState //this value holds the previous make in the case of a recomposition
) {
val vinDescriptionState = vinDescriptionFlow.collectAsState()
val context = LocalContext.current
val models =
SMSRoomDatabase
.getDatabase(context)
.vinMakeModel
.observeModelsByMake(vinDescriptionState.value.make)
.collectAsState(
initial = emptyList())
//if the make has changed, select the first model of that make
if(
vinDescriptionState.value.make != previousMake.value &&
models.value.size > 0
) {
previousMake.value = vinDescriptionState.value.make
vinDescriptionState.value.model = models.value.get(0)
}
val scrollState = rememberScrollState()
Row(
modifier = Modifier
.fillMaxWidth()
.height(IntrinsicSize.Max)
) {
val modelLabelString = "Model"
var expanded by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
modifier = Modifier
.weight(1f),
expanded = expanded,
onExpandedChange = {
expanded = !expanded
}
) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.menuAnchor(),
readOnly = true,
value = vinDescriptionState.value.model,
onValueChange = {
vinDescriptionState.value.model = it
},
label = {
Text(modelLabelString)
},
placeholder = {
Text(modelLabelString.toUpperCase(Locale.current))
},
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
}
)
ExposedDropdownMenu(
expanded = expanded,
scrollState = scrollState,
onDismissRequest = {
expanded = false
}
) {
models.value.forEachIndexed { index, item ->
DropdownMenuItem(
text = { Text(item) },
onClick = {
vinDescriptionFlow.value.model = item
expanded = false
}
)
}
}
}
}
}
Код: Выделить всё
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MakeSelection(
vinDescriptionFlow: MutableStateFlow,
) {
val vinDescriptionState = vinDescriptionFlow.collectAsState()
val context = LocalContext.current
val makeLabelString = "Make"
val makes =
SMSRoomDatabase
.getDatabase(context)
.vinMakeModel
.observeDistinctMakes()
.collectAsState(
initial = emptyList())
var expanded by remember { mutableStateOf(false) }
val scrollState = rememberScrollState()
Row(
modifier = Modifier
.fillMaxWidth()
.height(IntrinsicSize.Max)
) {
ExposedDropdownMenuBox(
modifier = Modifier
.weight(1f),
expanded = expanded,
onExpandedChange = {
expanded = !expanded
}
) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.menuAnchor(),
readOnly = true,
value = vinDescriptionState.value.make,
onValueChange = { make ->
//trying to trigger recomposition by copying the state and altering flow
vinDescriptionFlow.value = vinDescriptionState.value.clone().also { it.make = make }
//vinDescriptionState.value.make = it
},
label = {
Text(makeLabelString)
},
placeholder = {
Text(makeLabelString.toUpperCase(Locale.current))
},
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
}
)
ExposedDropdownMenu(
expanded = expanded,
scrollState = scrollState,
onDismissRequest = {
expanded = false
}
) {
makes.value.forEachIndexed { index, item ->
DropdownMenuItem(
text = { Text(item) },
onClick = {
vinDescriptionFlow.value.make = item
expanded = false
}
)
}
}
}
}
}
Код: Выделить всё
@Composable
fun VinEntryDialog(
vinDescriptionFlow: MutableStateFlow,
show: MutableState,
onConfirm: (MutableStateFlow) -> Unit) {
val vinDescriptionState = vinDescriptionFlow.collectAsState()
//clone the value and VinDescription Flow will be updated in onConfirm callback
val localVinDescriptionFlow: MutableStateFlow =
MutableStateFlow(vinDescriptionState.value.copy())
if(show.value)
AlertDialog(
onDismissRequest = {
show.value = false
},
confirmButton = {
TextButton(
onClick = {
vinDescriptionFlow.value = localVinDescriptionFlow.value
onConfirm(localVinDescriptionFlow)
}
) {
Text("Save")
}
},
dismissButton = {
TextButton(
onClick = {
show.value = false
}
) {
Text("Cancel")
}
},
text = {
val previousMake = remember { mutableStateOf(localVinDescriptionFlow.value.make) }
Column {
VinTextField(
vinDescriptionFlow = localVinDescriptionFlow)
MakeSelection(
vinDescriptionFlow = localVinDescriptionFlow)
ModelSelection(
vinDescriptionFlow = localVinDescriptionFlow,
previousMake = previousMake)
YearTitleRow(
vinDescriptionFlow = localVinDescriptionFlow)
ColorSelection(
vinDescriptionFlow = localVinDescriptionFlow)
}
})
}
Код: Выделить всё
override fun equals(compare: Any?): Boolean {
val other = compare as VinDescription
var equal =
vin == other.vin &&
make == other.make &&
model == other.model &&
year == other.year &&
titleNumber == other.titleNumber &&
hasTitle == other.hasTitle &&
titleState == other.titleState &&
color == other.color &&
licenseNumber == other.licenseNumber
if(vinImageFiles.size == other.vinImageFiles.size) {
if(vinImageFiles.size > 0)
vinImageFiles.forEachIndexed { index, thisImage ->
other.vinImageFiles.getOrNull(index)?.let { thatImage ->
equal = equal && thisImage.absolutePath == thatImage.absolutePath
}
}
} else {
return false
}
if(remoteVinImageFiles.size == other.remoteVinImageFiles.size) {
if(remoteVinImageFiles.size > 0)
remoteVinImageFiles.forEachIndexed { index, thisImage ->
other.remoteVinImageFiles.getOrNull(index)?.let { thatImage ->
equal = equal && thisImage.absolutePath == thatImage.absolutePath
}
}
} else {
return false
}
return equal
}
Код: Выделить всё
@Synchronized
@Throws(CloneNotSupportedException::class)
public override fun clone(): VinDescription {
val logger = LoggerFactory.getLogger(this.javaClass)
val vd = VinDescription()
vinImageFiles.forEach {
vd.vinImageFiles.add(it)
}
remoteVinImageFiles.forEach {
vd.remoteVinImageFiles.add(it)
}
vd.vin = this.vin
vd.make = this.make
vd.model = this.model
vd.year = this.year
vd.titleNumber = this.titleNumber
vd.hasTitle = this.hasTitle
vd.titleState = this.titleState
vd.color = this.color;
vd.licenseNumber = this.licenseNumber
logger.info("cloning complete!")
return vd
}
Код: Выделить всё
data class VinDescription(
var vin: String = "",
var make: String = "",
var model: String = "",
var year: String = "",
var titleNumber: String = "",
var hasTitle: String = "",
var titleState: String = "",
var color: String = "",
var licenseNumber: String = "",
var vinImageFiles: MutableList = mutableListOf(),
var remoteVinImageFiles: MutableList = mutableListOf()
)
Подробнее здесь: https://stackoverflow.com/questions/787 ... te-objects
Мобильная версия