Я бы хотел получить пользователя из моей базы данных комнат с помощью репозитория, а затем наблюдать за ним во фрагменте OverviewFragment.
Что я пробовал:
с использованием Observer во фрагменте, но я получил исключение NullPointerException.
с использованием @{overviewViewModel.user.email}
во фрагменте_overview. xml: приложение работает, но ничего не отображается.
Модульное тестирование и инструментальное тестирование с помощью FakeRepository. Тесты пройдены, и данные отображаются.
Что я использую:
Android Studio (до дата)
Kotlin
Архитектура MVVM
Шаблон репозитория, связанный с базой данных Room
Внедрение зависимостей в конструктор (для моделей представления)
ServiceLocator шаблон для тестирования
Поток пользователей (навигация)
Пользователь открывает приложение, заполняет форму и нажимает кнопку регистрации в элементе RegistrationFragment, затем переходит к элементу OverviewFragment, где находятся его данные (электронная почта , Пароль).
RegistrationViewModel:
class RegistrationViewModel(private val repository: IUserRepository) : ViewModel() {
private var viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
private val _user = MutableLiveData<User>()
val user: LiveData<User>
get() = _user
val email = MutableLiveData<String>()
val password = MutableLiveData<String>()
[...]
fun onRegister() {
val userEmail = email.value.toString()
val userPassword = password.value.toString()
registerUser(User(userEmail, userPassword))
}
private fun registerUser(newUser: User) = uiScope.launch {
repository.registerUser(newUser)
}
[...]
}
OverviewViewModel
class OverviewViewModel(val database: UserDatabaseDao,
private val userRepository: IUserRepository
) : ViewModel() {
private val _user = MutableLiveData<User>()
val user: LiveData<User>
get() = _user
init {
getUser()
}
private fun getUser() {
runBlocking {_user.value = userRepository.getUser().value }
}
OverviewFragment:
class OverviewFragment : Fragment() {
[...]
overviewViewModel.user.observe(this, Observer {
binding.apply {
textview.text = overviewViewModel.user.value!!.email
textview2.text = overviewViewModel.user.value!!.password
}
})
return binding.root
}
}
Репозиторий:
class UserRepository(private val dataSource: UserDatabaseDao,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO) :
IUserRepository {
override suspend fun registerUser(user: User) = withContext(ioDispatcher) {
dataSource.insert(user)
}
override suspend fun getUser(): LiveData<User?> = withContext(ioDispatcher) {
return@withContext dataSource.getUser()
}
override suspend fun getUser(email: String): LiveData<User?> = withContext(ioDispatcher) {
return@withContext dataSource.getUser(email)
}
}
DatabaseDao:
@Dao
interface UserDatabaseDao {
@Insert
fun insert(user: User)
@Query("SELECT * from user_table WHERE email = :key")
fun getUser(key: String): LiveData<User?>
@Query("SELECT * from user_table")
fun getUser(): LiveData<User?>
@Query("SELECT * from user_table")
fun getAllUsers(): LiveData<List<User>>
}
Примечание: есть только один пользователь в базе данных, один заполняет форму в регистрационном фрагменте.