Как сначала загрузить данные во вспомогательную ViewModel и передать их в основную базу данных Room одним нажатием кнопкAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как сначала загрузить данные во вспомогательную ViewModel и передать их в основную базу данных Room одним нажатием кнопк

Сообщение Anonymous »

Я новичок в Kotlin и сейчас пытаюсь создать небольшое приложение для электронных книг для своего проекта. У меня есть база данных комнат для книг, принадлежащих всем пользователям, и ViewModel, которая помогает ее заполнить.

Код: Выделить всё

@Entity
data class UsersBook(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
@ColumnInfo val idImage: Int,
@ColumnInfo val title: String,
@ColumnInfo val author: String,
@ColumnInfo val favourited: Boolean,
@ColumnInfo val categories: Category,
@ColumnInfo val nameOwner: String,
@ColumnInfo val rating: Double
)

Код: Выделить всё

//Composable for the StoreScreen from NavHost

with(LibraryRoutes.Store) {
composable(route) {
val userBooksVM = koinViewModel()

val addUserBookVm = koinViewModel()
val usersBookState by addUserBookVm.state.collectAsStateWithLifecycle()

val loggedUserVM = koinViewModel()
val stateUser by loggedUserVM.state.collectAsStateWithLifecycle()
StoreScreen(
state,
addUserBookVm.actions,
onSubmit = {
userBooksVM.addUserBook(usersBookState.toUserBook())
},
stateUser,
navController
)
}
}

Код: Выделить всё

//Helper ViewModel
data class AddNewUserBookState(
val idImage: Int = 0,
val title: String = "",
val author: String = "",
val favourited: Boolean = false,
val categories: Category = Category.Avventura,
val nameOwner: String = "",
val rating: Double = 0.0
) {
fun toUserBook() = UsersBook(
idImage = idImage,
title = title,
author = author,
favourited= favourited,
categories = categories,
nameOwner = nameOwner,
rating = rating
)
}
interface AddNewUserBookActions {
fun setImage(idImage: Int)
fun setTitle(title: String)
fun setAuthor(author: String)
fun setFavourited(favourited: Boolean)
fun setCategories(categories: Category)
fun setNameOwner(nameOwner: String)
fun setRating(rating: Double)
}

class AddUsersBooksViewModel : ViewModel() {
private val _state = MutableStateFlow(AddNewUserBookState())
val state = _state.asStateFlow()

val actions = object : AddNewUserBookActions {
override fun setImage(idImage: Int) =
_state.update { it.copy(idImage = idImage) }

override fun setTitle(title: String) =
_state.update { it.copy(title = title) }

override fun setAuthor(author: String) =
_state.update { it.copy(author = author) }

override fun setFavourited(favourited: Boolean) =
_state.update { it.copy(favourited= favourited) }

override fun setCategories(categories: Category) =
_state.update { it.copy(categories = categories) }

override fun setNameOwner(nameOwner: String) =
_state.update { it.copy(nameOwner = nameOwner) }

override fun setRating(rating: Double) =
_state.update { it.copy(rating = rating) }

}
}

Код: Выделить всё

//Database
data class UsersBooksState(val usersBooks: List)

class UsersBooksViewModel(private val repository: UsersBooksRepository) : ViewModel() {
val state = repository.books.map { UsersBooksState(usersBooks = it) }.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = UsersBooksState(emptyList())
)

fun addUserBook(usersBook: UsersBook) = viewModelScope.launch {
repository.upsert(usersBook)
}
}

Код: Выделить всё

//This is my StoreScreen

data class Book(
val idImage: Int,
val title: String,
val author: String,
val categories: Category,
val price: Double,
val discount: Int,
val rating: Double
)

@Composable
fun StoreScreen(
state: AddNewUserBookState,
actions: AddNewUserBookActions,
onSubmit: () ->  Unit,
usersState: LoggedUserState,
navController: NavHostController
) {
Column(modifier = Modifier.fillMaxSize()) {
val books = remember {
listOf(
Book(
R.drawable.caccia_aperta,
"Caccia Aperta",
"Rob Himmel",
Category.Fantasia,
6.99,
0,
5.0
),
Book(
R.drawable.ridi_che_e_gratis,
"Ridi che è gratis",
"I Carbonchi",
Category.Commedia,
3.50,
0,
4.5
),
Book(
R.drawable.rosa_di_tenebra,
"Rosa Di Tenebra",
"Peony Wentworth",
Category.Romanzo,
11.00,
10,
3.0
)
)
}

LazyRow(
modifier = Modifier.weight(0.5f),
horizontalArrangement = Arrangement.spacedBy(25.dp),
contentPadding = PaddingValues(7.dp, 0.dp, 3.dp, 0.dp)
) {
items(books) {
StoreLibraryItem(
it,
state,
actions,
onSubmit,
usersState,
navController
)
}
}
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun StoreLibraryItem(
item: Book,
state: AddNewUserBookState,
actions: AddNewUserBookActions,
onSubmit: () -> Unit,
usersState: LoggedUserState
) {
Column(
modifier = Modifier.width(167.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Row(
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically
) {

Button(onClick = {
actions.setImage(item.idImage)
actions.setTitle(item.title)
actions.setAuthor(item.author)
actions.setToRead(false)
actions.setCategories(item.categories)
actions.setNameOwner(usersState.username)
actions.setRating(item.rating)
onSubmit()
}) {
Text(text = "Buy")
}
}
}
}

По сути, у меня есть StoreScreen с серией книг, каждая из которых имеет кнопку «Купить», которая при нажатии помещает книги в базу данных UserBooks. Однако я не уверен, как с этим справиться, поскольку onClick в коде вызывает onSubmit до того, как все данные будут загружены во вспомогательную ViewModel, в результате чего в базе данных появятся строки с одним или несколькими отсутствующими полями.
Изначально у меня была аналогичная проблема со входом в систему, и кто-то здесь предложил мне использовать оператор When для управления навигацией после проверки имени пользователя и пароля, хотя я мог бы использовать что-то подобное, например TransactionScreen, но я не уверен, сработает ли это, а также это не поможет со вторым вопросом. Я также мог бы использовать предварительно заполненную базу данных для книг, но как мне обработать поле userOwner? поскольку база данных для пользователей находится в памяти, у каждого пользователя есть копия книги в базе данных UserBook, главным образом из-за поля «Избранное». .

Подробнее здесь: https://stackoverflow.com/questions/787 ... -main-room
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»