Хорошо, я постараюсь сделать это проще. Я пишу приложение, и один из его фрагментов содержит обзор переработчика, который отображает элементы в таблице Room. Когда таблица пуста, я должен отобразить заполнитель.
Я довольно новичок в MVVM, но подход, который я попытался использовать, заключался в добавлении заполнителя в макет (простое текстовое представление) и удалении его из макета, если таблица не пуста. Проблема в том, что каждая попытка определить, пуста ли таблица, не сработала. Я попробовал:
- Наличие простого запроса в DAO (код ниже) и вызов его в viewmodel. Затем из viewmodel я использую функцию в самом фрагменте. Мне кажется, что этот подход не работает из-за времени выполнения, поскольку функция viewmodel использует сопрограмму для правильной работы
- Попытка использовать адаптер recyclerview и его метод getItemCount, но всегда возвращает 0
Так что, в основном, я изо всех сил стараюсь просто удалить текстовое представление из макета, когда БД пуста, избегая при этом нарушения принципов MVVM. Вот некоторый полезный код
Функция DAO
@Query("SELECT * FROM Event LIMIT 1")
fun getAnyEvent(): EventResult?
Функция ViewModel
fun getAnyEvent() = viewModelScope.launch(Dispatchers.Default) {
eventDao.getAnyEvent()
}
Первый не подход
if (homeViewModel.getAnyEvent() != null) {
val homeMain: LinearLayout = v.findViewById(R.id.homeMain)
val placeholder: TextView = v.findViewById(R.id.noEvents)
homeMain.removeView(placeholder)
}
Адаптер
class EventAdapter internal constructor(context: Context) : RecyclerView.Adapter<EventAdapter.EventViewHolder>() {
private var events = emptyList<EventResult>() // Cached copy of events
private val appContext = context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EventViewHolder {
return EventViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.event_row, parent, false))
}
override fun onBindViewHolder(holder: EventViewHolder, position: Int) {
val current = events[position]
holder.setUpView(event = current)
}
inner class EventViewHolder (view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
private val favoriteButton: ImageView = view.favoriteButton
private val eventPerson: TextView = view.eventPerson
private val eventDate: TextView = view.eventDate
private val eventYears: TextView = view.eventYears
init {
view.setOnClickListener(this)
}
// Set every necessary text and click action in each row
fun setUpView(event: EventResult?) {
val personName = event?.name + " " + event?.surname
val formatter: DateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
val nextDate = event?.nextDate?.format(formatter)
val nextAge = appContext.getString(R.string.next_age_years) + ": " + (event?.nextDate?.year?.minus(event.originalDate.year)).toString()
eventPerson.text = personName
eventDate.text = nextDate
eventYears.text = nextAge
override fun onClick(v: View?) {
println("test")
}
}
internal fun setEvents(events: List<EventResult>) {
this.events = events
notifyDataSetChanged()
}
override fun getItemCount() = events.size
}
Какой подход я должен использовать? И что я делаю не так, используя этот шаблон? Как примечание стороны, переработчик работает, и я уже использую liveata, чтобы правильно наблюдать за изменениями.