Extended database model.

This commit is contained in:
sockenklaus
2022-07-19 15:28:16 +02:00
parent 967e16f011
commit c819c90269
13 changed files with 388 additions and 117 deletions

View File

@@ -2,11 +2,11 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 2, "version": 2,
"identityHash": "4f4222f215c1724a7401aa8d181012a4", "identityHash": "e86f0253ec49cbc67a601f90d5169a8a",
"entities": [ "entities": [
{ {
"tableName": "charges", "tableName": "charges",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `charge` REAL NOT NULL, `battery_id` TEXT NOT NULL, `date` TEXT NOT NULL, `createdTime` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(`id`))", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `charge` REAL NOT NULL, `battery_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `comment` TEXT NOT NULL DEFAULT '', `created_at` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP, `synced` INTEGER NOT NULL DEFAULT false, FOREIGN KEY(`battery_id`) REFERENCES `batteries`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@@ -23,20 +23,110 @@
{ {
"fieldPath": "batteryId", "fieldPath": "batteryId",
"columnName": "battery_id", "columnName": "battery_id",
"affinity": "TEXT", "affinity": "INTEGER",
"notNull": true "notNull": true
}, },
{ {
"fieldPath": "date", "fieldPath": "date",
"columnName": "date", "columnName": "date",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "comment",
"columnName": "comment",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "''"
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "CURRENT_TIMESTAMP"
},
{
"fieldPath": "synced",
"columnName": "synced",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_charges_battery_id",
"unique": false,
"columnNames": [
"battery_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_charges_battery_id` ON `${TABLE_NAME}` (`battery_id`)"
}
],
"foreignKeys": [
{
"table": "batteries",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"battery_id"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "batteries",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `declared_capacity` REAL DEFAULT NULL, `comment` TEXT NOT NULL DEFAULT '', `synced` INTEGER NOT NULL DEFAULT false, `created_at` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": true "notNull": true
}, },
{ {
"fieldPath": "createdTime", "fieldPath": "declaredCapacity",
"columnName": "createdTime", "columnName": "declared_capacity",
"affinity": "REAL",
"notNull": false,
"defaultValue": "NULL"
},
{
"fieldPath": "comment",
"columnName": "comment",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": true, "notNull": true,
"defaultValue": "''"
},
{
"fieldPath": "synced",
"columnName": "synced",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "CURRENT_TIMESTAMP" "defaultValue": "CURRENT_TIMESTAMP"
} }
], ],
@@ -44,33 +134,7 @@
"columnNames": [ "columnNames": [
"id" "id"
], ],
"autoGenerate": false "autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "batteries",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `declared_charge` REAL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "declaredCharge",
"columnName": "declared_charge",
"affinity": "REAL",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
}, },
"indices": [], "indices": [],
"foreignKeys": [] "foreignKeys": []
@@ -79,7 +143,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '4f4222f215c1724a7401aa8d181012a4')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e86f0253ec49cbc67a601f90d5169a8a')"
] ]
} }
} }

View File

@@ -0,0 +1,149 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "e86f0253ec49cbc67a601f90d5169a8a",
"entities": [
{
"tableName": "charges",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `charge` REAL NOT NULL, `battery_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `comment` TEXT NOT NULL DEFAULT '', `created_at` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP, `synced` INTEGER NOT NULL DEFAULT false, FOREIGN KEY(`battery_id`) REFERENCES `batteries`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "charge",
"columnName": "charge",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "batteryId",
"columnName": "battery_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "date",
"columnName": "date",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "comment",
"columnName": "comment",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "''"
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "CURRENT_TIMESTAMP"
},
{
"fieldPath": "synced",
"columnName": "synced",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_charges_battery_id",
"unique": false,
"columnNames": [
"battery_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_charges_battery_id` ON `${TABLE_NAME}` (`battery_id`)"
}
],
"foreignKeys": [
{
"table": "batteries",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"battery_id"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "batteries",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `declared_capacity` REAL DEFAULT NULL, `comment` TEXT NOT NULL DEFAULT '', `synced` INTEGER NOT NULL DEFAULT false, `created_at` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "declaredCapacity",
"columnName": "declared_capacity",
"affinity": "REAL",
"notNull": false,
"defaultValue": "NULL"
},
{
"fieldPath": "comment",
"columnName": "comment",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "''"
},
{
"fieldPath": "synced",
"columnName": "synced",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "CURRENT_TIMESTAMP"
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e86f0253ec49cbc67a601f90d5169a8a')"
]
}
}

View File

@@ -12,7 +12,7 @@ import com.sockenklaus.batterytracker.room.entities.Charge
@Database( @Database(
entities = [Charge::class, Battery::class], entities = [Charge::class, Battery::class],
version = 2 version = 3
) )
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class BatteryTrackerDB : RoomDatabase() { abstract class BatteryTrackerDB : RoomDatabase() {

View File

@@ -2,13 +2,11 @@ package com.sockenklaus.batterytracker.room.dao
import androidx.room.* import androidx.room.*
import com.sockenklaus.batterytracker.room.entities.Battery import com.sockenklaus.batterytracker.room.entities.Battery
import com.sockenklaus.batterytracker.room.entities.BatteryAndCharges
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface BatteryDao { interface BatteryDao {
@Insert
fun insertAll(vararg batteries: Battery)
@Insert @Insert
fun insert(battery: Battery) fun insert(battery: Battery)
@@ -16,11 +14,19 @@ interface BatteryDao {
fun delete(battery: Battery) fun delete(battery: Battery)
@Update @Update
fun updateBatteries(vararg batteries: Battery): Int fun updateBattery(battery: Battery): Int
@Query("Select * FROM batteries") @Query("Select * FROM batteries")
fun getBatteries(): Flow<List<Battery>> fun getBatteries(): Flow<List<Battery>>
@Query("Select * FROM batteries WHERE id = :id") @Query("Select * FROM batteries WHERE id = :id")
fun getBatteryById(id: String): Flow<Battery> fun getBatteryById(id: Int): Flow<Battery>
@Transaction
@Query("SELECT * FROM batteries")
fun getBatteriesAndCharges(): Flow<List<BatteryAndCharges>>
@Transaction
@Query("SELECT * FROM batteries WHERE id = :id")
fun getBatteryAndCharges(id: Int): Flow<BatteryAndCharges>
} }

View File

@@ -1,14 +1,12 @@
package com.sockenklaus.batterytracker.room.dao package com.sockenklaus.batterytracker.room.dao
import androidx.room.* import androidx.room.*
import com.sockenklaus.batterytracker.room.entities.BatteryAndCharges
import com.sockenklaus.batterytracker.room.entities.Charge import com.sockenklaus.batterytracker.room.entities.Charge
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface ChargeDao { interface ChargeDao {
@Insert
fun insertAll(vararg charges: Charge)
@Insert @Insert
fun insert(charge: Charge) fun insert(charge: Charge)
@@ -16,11 +14,15 @@ interface ChargeDao {
fun delete(charge: Charge): Int fun delete(charge: Charge): Int
@Update @Update
fun updateCharges(vararg charges: Charge): Int fun updateCharge(charge: Charge): Int
@Query("Select * FROM charges") @Query("Select * FROM charges")
fun getCharges(): Flow<List<Charge>> fun getCharges(): Flow<List<Charge>>
@Query("Select * FROM charges WHERE id = :id") @Query("Select * FROM charges WHERE id = :id")
fun getChargeById(id: Int): Flow<Charge> fun getChargeById(id: Int): Flow<Charge>
@Transaction
@Query("SELECT * FROM batteries WHERE id = :id")
fun getBatteryAndCharges(id: Int): Flow<BatteryAndCharges>
} }

View File

@@ -1,14 +1,29 @@
package com.sockenklaus.batterytracker.room.entities package com.sockenklaus.batterytracker.room.entities
import androidx.annotation.NonNull
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import java.time.LocalDateTime
@Entity(tableName = "batteries") @Entity(tableName = "batteries")
data class Battery( data class Battery(
@PrimaryKey
val id: String,
@ColumnInfo(name = "declared_charge") @PrimaryKey(autoGenerate = true)
val declaredCharge: Double?, @NonNull
val id: Int = 0,
val name: String,
@ColumnInfo(name = "declared_capacity", defaultValue = "NULL")
val declaredCapacity: Double? = null,
@ColumnInfo(defaultValue = "")
val comment: String = "",
@ColumnInfo(defaultValue = "false")
val synced: Boolean = false,
@ColumnInfo(name = "created_at", defaultValue = "CURRENT_TIMESTAMP")
val createdAt: LocalDateTime = LocalDateTime.now()
) )

View File

@@ -0,0 +1,15 @@
package com.sockenklaus.batterytracker.room.entities
import androidx.room.Embedded
import androidx.room.Relation
data class BatteryAndCharges(
@Embedded
val battery: Battery,
@Relation(
parentColumn = "id",
entityColumn = "battery_id"
)
val charges: List<Charge>
)

View File

@@ -1,23 +1,40 @@
package com.sockenklaus.batterytracker.room.entities package com.sockenklaus.batterytracker.room.entities
import androidx.room.ColumnInfo import androidx.room.*
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.time.LocalDateTime import java.time.LocalDateTime
@Entity(tableName = "charges") @Entity(
tableName = "charges",
foreignKeys = [
ForeignKey(
entity = Battery::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("battery_id"),
onDelete = ForeignKey.CASCADE
)],
indices = [Index(value = ["battery_id"])]
)
data class Charge( data class Charge(
@PrimaryKey @PrimaryKey(autoGenerate = true)
val id: Int, val id: Int = 0,
val charge: Double, val charge: Double,
@ColumnInfo(name = "battery_id") @ColumnInfo(name = "battery_id")
val batteryId: String, val batteryId: Int,
val date: String, val date: LocalDateTime,
@ColumnInfo(defaultValue = "CURRENT_TIMESTAMP") @ColumnInfo(defaultValue = "")
val createdTime: String val comment: String = "",
@ColumnInfo(
name = "created_at",
defaultValue = "CURRENT_TIMESTAMP"
)
val createdAt: LocalDateTime = LocalDateTime.now(),
@ColumnInfo(defaultValue = "false")
val synced: Boolean = false
) )

View File

@@ -16,17 +16,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.asLiveData import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.sockenklaus.batterytracker.R import com.sockenklaus.batterytracker.R
import com.sockenklaus.batterytracker.databinding.FragmentAddBatteryBinding import com.sockenklaus.batterytracker.databinding.FragmentAddBatteryBinding
import com.sockenklaus.batterytracker.room.BatteryTrackerDB
import com.sockenklaus.batterytracker.room.entities.Battery import com.sockenklaus.batterytracker.room.entities.Battery
import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme
import com.sockenklaus.batterytracker.ui.theme.Gray500 import com.sockenklaus.batterytracker.ui.theme.Gray500
import com.sockenklaus.batterytracker.util.validateDecimal import com.sockenklaus.batterytracker.util.validateDecimal
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
/** /**
* A simple [Fragment] subclass. * A simple [Fragment] subclass.
@@ -43,28 +39,17 @@ class AddBatteryFragment : Fragment() {
): View { ): View {
_binding = FragmentAddBatteryBinding.inflate(inflater, container, false) _binding = FragmentAddBatteryBinding.inflate(inflater, container, false)
val db = BatteryTrackerDB.getInstance(requireContext()) val model = ViewModelProvider(this)[AddBatteryViewModel::class.java]
val view = binding.root val view = binding.root
/** var batteries = emptyList<Battery>()
* TODO: Move database interactions to ViewModel!
*/
val batteries = db.batteryDao().getBatteries().asLiveData()
var listBatteries = emptyList<Battery>()
batteries.observe(viewLifecycleOwner) { model.batteries.observe(viewLifecycleOwner) {
listBatteries = it batteries = it
} }
binding.root.setContent { binding.root.setContent {
BatteryTrackerTheme { BatteryTrackerTheme {
var batteryId by remember { mutableStateOf("") }
var batteryHasError by remember { mutableStateOf(false) }
var batteryHelperId: Int? by remember { mutableStateOf(null) }
var declaredCapacity by remember { mutableStateOf("")}
var capacityHasError by remember { mutableStateOf(false) }
var capacityHelperId: Int? by remember { mutableStateOf(null) }
val outerPadding = 24.dp val outerPadding = 24.dp
val innerPadding = 16.dp val innerPadding = 16.dp
@@ -73,47 +58,47 @@ class AddBatteryFragment : Fragment() {
Modifier.padding(outerPadding) Modifier.padding(outerPadding)
) { ) {
MyOutlinedTextField( MyOutlinedTextField(
value = batteryId, value = model.batteryName,
onValueChange = { value -> onValueChange = { value ->
batteryId = value model.batteryName = value
batteryHasError = false model.batteryHasError = false
batteryHelperId = null model.batteryHelperId = null
if(listBatteries.any{ it.id.lowercase() == value.lowercase() }){ if(batteries.any{ it.name.lowercase() == value.lowercase() }){
batteryHasError = true model.batteryHasError = true
batteryHelperId = R.string.helper_battery_not_unique model.batteryHelperId = R.string.helper_battery_not_unique
} }
}, },
labelId = R.string.hint_enter_battery_id, labelId = R.string.hint_enter_battery_name,
leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") }, leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") },
isError = batteryHasError, isError = model.batteryHasError,
helperTextId = batteryHelperId helperTextId = model.batteryHelperId
) )
Spacer(Modifier.size(innerPadding)) Spacer(Modifier.size(innerPadding))
MyOutlinedTextField( MyOutlinedTextField(
value = declaredCapacity, value = model.declaredCapacity,
onValueChange = { onValueChange = {
declaredCapacity = validateDecimal(it, declaredCapacity) model.declaredCapacity = validateDecimal(it, model.declaredCapacity)
capacityHasError = false model.capacityHasError = false
capacityHelperId = null model.capacityHelperId = null
}, },
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") },
isError = capacityHasError, isError = model.capacityHasError,
helperTextId = capacityHelperId helperTextId = model.capacityHelperId
) )
Spacer(Modifier.size(outerPadding)) Spacer(Modifier.size(outerPadding))
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
onClick = { onClick = {
if(batteryId.isBlank()) batteryHasError = true if(model.batteryName.isBlank()) model.batteryHasError = true
if(declaredCapacity.isBlank()) capacityHasError = true if(model.declaredCapacity.isBlank()) model.capacityHasError = true
if(!batteryHasError && !capacityHasError){ if(!model.batteryHasError && !model.capacityHasError){
saveBattery(batteryId, declaredCapacity) model.saveBattery(model.batteryName, model.declaredCapacity)
} }
}, },
icon = { Icon(Icons.Default.Save, "Icon Save") }, icon = { Icon(Icons.Default.Save, "Icon Save") },
@@ -161,17 +146,6 @@ class AddBatteryFragment : Fragment() {
) )
} }
private fun saveBattery(
id: String,
declaredCapacity: String
) {
val db = BatteryTrackerDB.getInstance(requireContext())
lifecycleScope.launch(Dispatchers.IO){
db.batteryDao().insert(Battery(id, declaredCapacity.toDouble()))
}
}
/*companion object { /*companion object {
* Use this factory method to create a new instance of * Use this factory method to create a new instance of

View File

@@ -1,13 +1,42 @@
package com.sockenklaus.batterytracker.ui.fragments.add_battery package com.sockenklaus.batterytracker.ui.fragments.add_battery
import android.app.Application import android.app.Application
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.asLiveData import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.sockenklaus.batterytracker.room.BatteryTrackerDB import com.sockenklaus.batterytracker.room.BatteryTrackerDB
import com.sockenklaus.batterytracker.room.entities.Battery
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class AddBatteryViewModel(application: Application): AndroidViewModel(application) { class AddBatteryViewModel(application: Application): AndroidViewModel(application) {
private val db = BatteryTrackerDB.getInstance(application) private val db = BatteryTrackerDB.getInstance(application)
private val batteries = db.batteryDao().getBatteries().asLiveData() val batteries = db.batteryDao().getBatteries().asLiveData()
var batteryName by mutableStateOf("")
var batteryHasError by mutableStateOf(false)
var batteryHelperId: Int? by mutableStateOf(null)
var declaredCapacity by mutableStateOf("")
var capacityHasError by mutableStateOf(false)
var capacityHelperId: Int? by mutableStateOf(null)
fun saveBattery(
name: String,
declaredCapacity: String? = null,
){
val battery = Battery(
name = name,
declaredCapacity = declaredCapacity?.toDouble()
)
viewModelScope.launch(Dispatchers.IO){
db.batteryDao().insert(battery)
}
}
} }

View File

@@ -50,7 +50,7 @@ class AddChargeFragment : Fragment() {
viewModel = ViewModelProvider(this)[AddChargeViewModel::class.java] viewModel = ViewModelProvider(this)[AddChargeViewModel::class.java]
var items = emptyList<Battery>() var items = emptyList<Battery>()
viewModel.allBatteryIds.observe(this.viewLifecycleOwner){ viewModel.batteries.observe(this.viewLifecycleOwner){
items = it items = it
} }
@@ -79,7 +79,7 @@ class AddChargeFragment : Fragment() {
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(), colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
val filteringOptions = items.filter { it.id.contains(viewModel.batteryId.text, ignoreCase = true)} val filteringOptions = items.filter { it.name.contains(viewModel.batteryId.text, ignoreCase = true)}
if(filteringOptions.size > 1 && viewModel.batteryId.text.isNotBlank()) bIdExpanded = true if(filteringOptions.size > 1 && viewModel.batteryId.text.isNotBlank()) bIdExpanded = true
if(filteringOptions.isNotEmpty()) { if(filteringOptions.isNotEmpty()) {
ExposedDropdownMenu( ExposedDropdownMenu(
@@ -90,13 +90,13 @@ class AddChargeFragment : Fragment() {
DropdownMenuItem( DropdownMenuItem(
onClick = { onClick = {
viewModel.batteryId = TextFieldValue( viewModel.batteryId = TextFieldValue(
text = filteringOption.id, text = filteringOption.name,
selection = TextRange(filteringOption.id.length) selection = TextRange(filteringOption.name.length)
) )
bIdExpanded = false bIdExpanded = false
} }
) { ) {
Text(filteringOption.id) Text(filteringOption.name)
} }
} }
} }

View File

@@ -17,7 +17,7 @@ import java.time.LocalDateTime
class AddChargeViewModel(application: Application) : AndroidViewModel(application) { class AddChargeViewModel(application: Application) : AndroidViewModel(application) {
private val db = BatteryTrackerDB.getInstance(application) private val db = BatteryTrackerDB.getInstance(application)
var allBatteryIds: LiveData<List<Battery>> = db.batteryDao().getBatteries().asLiveData() var batteries: LiveData<List<Battery>> = db.batteryDao().getBatteries().asLiveData()
var batteryId: TextFieldValue by mutableStateOf(TextFieldValue("")) var batteryId: TextFieldValue by mutableStateOf(TextFieldValue(""))
var date: LocalDateTime by mutableStateOf(LocalDateTime.now()) var date: LocalDateTime by mutableStateOf(LocalDateTime.now())

View File

@@ -22,11 +22,11 @@
<string name="charge">Charge</string> <string name="charge">Charge</string>
<string name="hint_charge">Enter Charge in Ah</string> <string name="hint_charge">Enter Charge in Ah</string>
<string name="select_battery_id">Select Battery ID</string> <string name="select_battery_id">Select Battery ID</string>
<string name="hint_enter_battery_id">Enter Battery ID</string> <string name="hint_enter_battery_name">Enter Battery Name</string>
<string name="hint_enter_declared_capacity">Enter declared capacity</string> <string name="hint_enter_declared_capacity">Enter declared capacity</string>
<string name="declared_capacity">Declared Capacity</string> <string name="declared_capacity">Declared Capacity</string>
<string name="button_save_battery">Save Battery</string> <string name="button_save_battery">Save Battery</string>
<string name="title_activity_add_battery">AddBattery</string> <string name="title_activity_add_battery">AddBattery</string>
<string name="helper_required">* Required</string> <string name="helper_required">* Required</string>
<string name="helper_battery_not_unique">Battery-ID not unique!</string> <string name="helper_battery_not_unique">Battery-Name not unique!</string>
</resources> </resources>