从视图模型中删除 UI 元素检查 table 是否为空

Remove UI element checking if table is empty from the viewmodel

好的,我会尽量保持简单。我正在编写一个应用程序,其中一个片段包含一个 recyclerview,它显示 Room table 内的元素。当 table 为空时,我应该显示一个占位符。

我对 MVVM 很陌生,但我尝试遵循的方法是将占位符添加到布局(一个简单的文本视图),如果 table 不为空,则将其从布局中删除。问题是,每次尝试确定 table 是否为空都没有用。我试过的是:

所以基本上我很努力地在数据库为空时简单地从布局中删除文本视图,同时避免破坏 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

}

我应该使用什么方法?使用这种模式我做错了什么? 作为旁注,recyclerview 有效,我已经在使用实时数据来正确观察变化。

看来你只有一个需要——在你的片段中知道你的数据库查询是否 return 0 条或更多条记录。您是否尝试过为此使用 LiveData(没有协程)? (你提到了,但不清楚)

  1. 您的 DAO 应该 return LiveData 值。通过这个房间,“开箱即用”将以在线模式(当然,在后台线程中)获取您的 ViewModel 实际查询结果。

fun getAnyEvent(): LiveData<List<EventResult>>

  1. 在您的 ViewModel 中,您也可以使用 LiveData 声明字段

val eventResult: LiveData<List<EventResult>> = eventDao.getAnyEvent()

  1. 在你的片段中,你只需观察你的 eventResult,你可以根据列表大小用你的 UI 做任何你想做的事(如果它是 0,然后删除你的视图存根)

    homeViewModel.eventResult.observe(viewLifecycleOwner, Observer { eventList -> yourAdapter.setEvents(eventList)})

Here 是 Google 的 Codelab,包含所有这些东西,例如