【问题标题】:Room Data doesn't show in the RecyclerList房间数据未显示在 RecyclerList 中
【发布时间】:2021-08-09 18:58:11
【问题描述】:

这是第一次使用房间数据,同时也使用 MVVM 模式。目的是我希望我的数据出现在 RecyclerList 上,但它没有关闭,也没有向我显示任何错误,它只是显示为空。

这是我的数据库类:

@Database(entities = [Plant::class, Plant_Category::class], version = 1)
abstract class PlantDatabase:RoomDatabase() {
    abstract fun plantDao(): PlantOperations
    abstract fun plantCategoryDao(): PlantCategoryOperations

    companion object {
        private var INSTANCE: PlantDatabase? = null
             
        fun getDatabase(context: Context): PlantDatabase {
            if (INSTANCE == null) {

                INSTANCE = Room.databaseBuilder(
                    context.applicationContext,
                    PlantDatabase::class.java, DB_NAME // contains directory of sqlite database
                ) 
                    .fallbackToDestructiveMigration()
                    .build()
            }

            return INSTANCE!!
        }
    }
}

我的道课:

@Dao
interface PlantOperations {
    @Query("SELECT * FROM Plant")
    fun getAll(): Flow<List<Plant>>

    @Insert
    fun insertPlant( plant: Plant)

    @Delete
    fun delete(plant:Plant)

    @Update
    fun updatePlant(plant:Plant)}

这是我的存储库类:

class PlantRepository(application:Application){
    private var allPlants = MutableLiveData<List<Plant>>()

    private val plantDAO = PlantDatabase.getDatabase(application).plantDao()

    init {
        CoroutineScope(Dispatchers.IO).launch {
            val plantData = plantDAO.getAll()
            plantData.collect{
                allPlants.postValue(it)
            }
        }
    }
    fun getAllPlants(): MutableLiveData<List<Plant>> {
        return allPlants
    }
    

}

我的 Viewmodel 类:

class PlantViewModel(
            application: Application
    ): AndroidViewModel(application) {

        private var repository = PlantRepository(application)

        private var _allPlants = repository.getAllPlants()

        val allPlants: MutableLiveData<List<Plant>>
            get() = _allPlants
    }

我在 Fragment 中的回收站:

override fun onCreateView(inflater: LayoutInflater,
                               container: ViewGroup?, savedInstanceState: Bundle?): View? {

        lateinit var  photoAdapter: Photo_Adapter
        lateinit var plantViewModel: PlantViewModel

       
        val view: View = inflater.inflate(R.layout.fragment_edit__form, container, false)
        val fab = view.findViewById(R.id.floatingActionButton) as FloatingActionButton
        val recyclerView = view.findViewById(R.id.recyclerView) as RecyclerView
          
      

        recyclerView.layoutManager = GridLayoutManager(context, 2)
        photoAdapter = Photo_Adapter(context)
        recyclerView.adapter = photoAdapter

         plantViewModel = ViewModelProvider(this).get(PlantViewModel::class.java)
        plantViewModel.allPlants.observe(viewLifecycleOwner, androidx.lifecycle.Observer {
            photoAdapter.setDataList(it)
        })

       // photoAdapter.setDataList(dataList)
        //Floating button that opens the Form in order to add plant
        fab?.setOnClickListener {

            val intent = Intent(view.context, Edit_Form::class.java)
           startActivity(intent);
        }
        return view
    }


这是我的适配器类:

class Photo_Adapter(var context: Context?) : RecyclerView.Adapter<Photo_Adapter.ViewHolder>() {

        var dataList = emptyList<Plant>()

        internal fun setDataList(dataList: List<Plant>) {
            this.dataList = dataList
            notifyDataSetChanged()
        }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // Get the data model based on position
        var data = dataList[position]


        holder.title.text = data.name
        holder.desc.text = data.type.toString()


        holder.image.setImageResource(data.image)
        holder.relativeLayout.setOnClickListener { view -> //Toast.makeText(view.getContext(),"click on item: "+model.getTitle(),Toast.LENGTH_LONG).show();
            val intent = Intent(view.context, PlantDetails::class.java)
            intent.putExtra("plant_name", data.name)
            intent.putExtra("plant_image",data.image)
            intent.putExtra("plant_type", data.type.type)
            intent.putExtra("plant_water", data.type.water_time)
            intent.putExtra("plant_details", data.type.details)
            view.context.startActivity(intent)
    }

}
        // Provide a direct reference to each of the views with data items

        class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            var image: ImageView
            var title: TextView
            var desc: TextView
            var relativeLayout: CardView

            init {
                image = itemView.findViewById(R.id.image)
                title = itemView.findViewById(R.id.title)
                desc = itemView.findViewById(R.id.desc)
                relativeLayout = itemView.findViewById<View>(R.id.relativeLayout) as CardView
            }

        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Photo_Adapter.ViewHolder {

            // Inflate the custom layout
            var view = LayoutInflater.from(parent.context).inflate(R.layout.photo_layout, parent, false)
            return ViewHolder(view)
        }


        //  total count of items in the list
        override fun getItemCount() = dataList.size

}

也许我忘了添加一些东西?无论如何,我将感谢您的帮助。

【问题讨论】:

  • android-studio 标签用于当您询问有关 IDE 本身的问题时,您在这里得到的任何答案似乎都取决于 IDE,因此我已将其从您的帖子,如果您不询问 IDE,则无需添加它

标签: android kotlin android-room android-mvvm


【解决方案1】:

您不应该观察存储库中的数据,您的活动/视图应该观察这些数据。看看这个:

首先,将此依赖项添加到您的 gradle:

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"

然后在您的存储库中

class PlantRepository(application:Application){
     private val plantDAO = PlantDatabase.getDatabase(application).plantDao()
     fun getAllPlants(): Flow<List<Plant>> = plantDAO.getAll()
}

在您的视图模型中:

class PlantViewModel(
        application: Application
): AndroidViewModel(application) {
    private var repository = PlantRepository(application)
    val allPlants = repository.getAllPlants()
                   .flowOn(Dispatchers.IO)
                   .asLiveData()
}

您的活动很好,但请检查您的适配器,确保您通知适配器您的列表已更改。 你也可以在你的视图上工作(收集)流,但这取决于你

【讨论】:

  • 我听从了你的建议,但没有奏效我还在代码中添加了我的适配器。
  • 代码没有问题,你确定你的数据库中有数据吗?如果您在片段的 photoAdapter.setDataList(...) 中设置断点,它会被调用吗?
  • 我检查了数据库中有数据我想我会做一个断点
  • 它告诉我列表大小为 0,即使数据库包含数据
  • 所以,你的 dao 出了点问题,我可以看到你使用 Flow 作为返回类型,检查你是否有这 3 个依赖项: implementation "androidx.room:room-runtime:2.3.0 " 实现 "androidx.room:room-ktx:2.3.0" kapt "androidx.room:room-compiler:2.3.0"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
  • 2022-12-19
  • 1970-01-01
  • 2018-01-27
相关资源
最近更新 更多