无法获取正确的用户ID,无法为登录用户分配备注。
嘿,在过去的两周里,我一直在努力解决一个问题,同时使用Jetpack Compose和Room Database在Android Studio中创建一个支持登录的笔记应用程序。我刚开始学习,这个问题让我抓狂,因为我知道有经验的人可能会在5分钟内解决这个问题。
首先,我想提一下,我在论坛text上发现了一个类似的问题,但提供的解决方案在我的情况下不起作用,我甚至试图向ChatGPT寻求帮助,但仍然不起作用。
下面,我将提供LoginRegisterViewModel、NotesViewModel和CreateNoteComposable函数的代码,我将在其中调用登录用户。对不起,代码混乱,但这是我的代码的“最后版本”,当我试图修复这个:/
登录注册视图模型:
class LoginRegisterViewModel(app: Application) : AndroidViewModel(app) {
private val repo = UserRepository(app.applicationContext)
private var userExist = false
private val currentUser = MutableStateFlow<User?>(null)
private var userId : Int? = null
suspend fun checkPassword(username: String, password: String): Boolean {
return withContext(Dispatchers.IO) {
val user = getUserByLoginAndPassword(username, password)
user != null
}
}
fun getUserId(): Int? {
println(userId)
return userId
}
private fun setCurrentUser(user: User) {
currentUser.value = user
userId = user.id
}
suspend fun checkIfUserExists(loginValue: String): Boolean {
return withContext(Dispatchers.IO) {
val user = repo.getUserByLogin(loginValue)
user != null
}
}
private suspend fun getUserByLoginAndPassword(
loginValue: String,
passwordValue: String
): User? {
return repo.getUserByLoginAndPassword(loginValue, passwordValue)
}
suspend fun login(loginValue: String, passwordValue: String): Boolean {
return withContext(Dispatchers.IO) {
val user = getUserByLoginAndPassword(loginValue, passwordValue)
if (user != null) {
setCurrentUser(user)
userId = repo.getUserId(loginValue)
println(currentUser.value)
true
} else {
false
}
}
}
fun logout() {
currentUser.value = null
}
fun registerUser(
nameValue: String,
loginValue: String,
passwordValue: String,
confirmPasswordValue: String
) {
viewModelScope.launch(Dispatchers.IO) {
if (passwordValue == confirmPasswordValue) {
userExist = false
val user = User(
nameValue = nameValue,
loginValue = loginValue,
passwordValue = passwordValue
)
repo.insert(user)
} else {
userExist = true
}
}
}
}
NotesViewModel:
class NotesViewModel(
private val repo: NotesRepository, private val userId: Int?
) : ViewModel() {
val getNotesByUserId: List<Note> = runBlocking { repo.getNotesByUserId(userId) }
fun deleteNotes(note: Note) {
viewModelScope.launch(Dispatchers.IO) {
repo.deleteNote(note)
}
}
fun updateNote(note: Note) {
viewModelScope.launch(Dispatchers.IO) {
repo.updateNote(note)
}
}
fun createNote(title: String, note: String, userId: Int?) {
viewModelScope.launch(Dispatchers.IO) {
repo.insertNote(Note(title = title, note = note, userId = userId))
println(userId)
}
}
suspend fun getNote(noteId: Int): Note? {
return repo.getNoteById(noteId)
}
}
@Suppress("UNCHECKED_CAST")
class NotesViewModelFactory(
private val repo: NotesRepository, private val loginRegisterViewModel: LoginRegisterViewModel
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return NotesViewModel(repo, loginRegisterViewModel.getUserId()) as T
}
}
CreateNote可组合函数:
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "UnusedMaterialScaffoldPaddingParameter")
@Composable
fun CreateNote(
navController: NavController,
viewModel: NotesViewModel,
userId: Int?
) {
val currentNote = remember {
mutableStateOf("")
}
val currentTitle = remember {
mutableStateOf("")
}
val saveButtonState = remember {
mutableStateOf(false)
}
val currentUser = remember {
mutableStateOf(userId)
}
println(currentUser)
NotepadTheme {
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
Scaffold(
topBar = {
AppBar(
title = "Create Note",
onIconClick = {
viewModel.createNote(
currentTitle.value,
currentNote.value,
currentUser.value
)
navController.popBackStack()
},
icon = {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.save),
contentDescription = stringResource(R.string.save_note),
tint = Color.Black,
)
},
iconState = remember { mutableStateOf(true) }
)
},
) {
Column(
Modifier
.padding(12.dp)
.fillMaxSize()
) {
TextField(
value = currentTitle.value,
modifier = Modifier.fillMaxWidth(),
onValueChange = { value ->
currentTitle.value = value
saveButtonState.value =
currentTitle.value != "" && currentNote.value != ""
},
colors = TextFieldDefaults.textFieldColors(
cursorColor = Color.Black,
focusedLabelColor = Color.Black
),
label = { Text(text = "Title") }
)
Spacer(modifier = Modifier.padding(12.dp))
TextField(
value = currentNote.value,
modifier = Modifier
.fillMaxHeight(0.5f)
.fillMaxWidth(),
onValueChange = { value ->
currentNote.value = value
saveButtonState.value =
currentTitle.value != "" && currentNote.value != ""
},
colors = TextFieldDefaults.textFieldColors(
cursorColor = Color.Black,
focusedLabelColor = Color.Black
),
label = { Text(text = "Note") }
)
}
}
}
}
}
提前感谢任何形式的帮助!
2条答案
按热度按时间gfttwv5a1#
我已经找到了一种将userId传递到NotesList页面的方法。首先,删除我在第一个答案中所说的所有更改,并从NotesViewModel类中删除用户对象参数。
我在你的代码中看到,在LoginRegisterViewModel中,你有currentUser的流对象,它从数据库中检索当前用户对象,我测试了它,以了解它是否正确地获取值,所以你不需要任何额外的方法来获取userId。
在NotesList组合中添加userId参数并像我一样更改路由,以便在路由参数中将userId从登录页面发送到NotesList页面。
在登录页面中,您将如何导航
最后在NotesListPage中修改NotesViewModel中userId的值
NotesViewModel中的这些代码行将使用userId检索notes列表。
在做了所有这些更改之后,出现了一个关于userId生成的错误,所以它所做的就是从Entity类中删除Unique key参数并保持简单,autoGenerate = true属性足以生成新的id。
完成此更改后,您还必须更改RoomDatabase版本并设置迁移,如果您不想提及迁移,只需添加.fallbackToDestructiveMigration()。
lnxxn5zx2#
在你的dao类中,你可以这样做,通过传入用户名来获取用户id。
然后将此函数添加到存储库中,然后在NotesViewModel中创建一个mutableStateOf Int,并将userId传递到notesViewModel的构造函数中,而不是传递整个user对象
最后,在可组合中,您可以执行以下操作:从参数中删除userId
你应该通过这种方式获取TheUser id,你可以在进一步的函数中使用它:)