插入Room数据库后,LiveData无法更新

时间:2019-04-29 10:34:04

标签: android android-room android-livedata

我的项目基本上允许用户创建产品列表,可以在其中添加不同的产品。因此,就我而言,我的实体之间存在的关系是多对多的:我有一个表,用于安装应用程序时添加的所有产品,我有一个表,其中包含用户创建的列表,最后我有一个表,记录用户将产品添加到列表中的时间。

我遇到的问题是,在用户将产品添加到列表中之后,活动中观察到的LiveData不会更新列表,我无法弄清原因。

活动(产品代码由用户在为结果而启动的另一个活动中引入):

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_list_of_products)

        // Get the listname from the bundle
        listName = intent.extras.getString(resources.getString(R.string.INTENT_EXTRA_LISTNAME))

        // Set up the ViewModel
        viewModel = ViewModelProviders.of(this, ListOfProductsViewModelFactory(application, listName)).get(ListOfProductsViewModel::class.java)

        // RecyclerView setup
        val recyclerView = findViewById<RecyclerView>(R.id.productRecyclerView)
        val mAdapter = ProductAdapter(this)
        recyclerView.adapter = mAdapter
        recyclerView.layoutManager = LinearLayoutManager(this)
        viewModel!!.getProductsInProductList().observe(this, Observer {
            products -> mAdapter.setProducts(products!!)
        })
    }

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if(requestCode == NEW_PRODUCT_ACTIVITY_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
            val code = data!!.extras.getString(resources.getString(R.string.ADD_MANUALLY_ACTIVITY_REPLY))
            val resultOfInsertion = viewModel!!.insertProductInProductList(code)
            if(resultOfInsertion) {
                Toast.makeText(applicationContext, "${code} successful added",
                    Toast.LENGTH_LONG).show()
            } else {
                Toast.makeText(applicationContext, "${code} was not added",
                    Toast.LENGTH_LONG).show()
            }
        }

        else {
            Toast.makeText(applicationContext, "Insertion cancelled",
                Toast.LENGTH_LONG).show()
        }
    }

ViewModel:

private var mRepo = ProductsInProductListRepository(application, listName)
    private val productsInProductList = mRepo.getProductsInProductList()

    fun getProductsInProductList() : LiveData<List<Product>> {
        return productsInProductList
    }

    fun insertProductInProductList(code: String) : Boolean {
        return mRepo.insertProductInProductList(code)
    }

存储库:

private var productsInProductListDao : ProductsInProductListDao
    private var productsInProductList : LiveData<List<Product>>
    private val listName : String

    constructor(application : Application, listName: String) {
        val db = ProductDatabase.getProductDatabase(application)
        this.productsInProductListDao = db!!.productsInProductListDao()
        this.listName = listName
        this.productsInProductList = productsInProductListDao.getProducstForProductList(listName)
    }

    fun getProductsInProductList() : LiveData<List<Product>> {
        return productsInProductList
    }

    fun insertProductInProductList(productCode : String) : Boolean {
        if(isProductAlreadyAdded(productCode)) {
            return false
        }
        InsertProductInProductListAsync(productsInProductListDao, listName).execute(productCode)
        return true
    }

    private fun isProductAlreadyAdded(productCode : String): Boolean {
        return productsInProductListDao.getProductAddedToCertainList(listName, productCode).isNotEmpty()
    }

DAO:

@Dao
interface ProductsInProductListDao {

    @Insert(onConflict = OnConflictStrategy.FAIL)
    fun insertProductInProductList(productInProductList: ProductsInProductList)

    @Query("SELECT code, model, pvpr, qtr, segmentation FROM product_table INNER JOIN products_in_productlist_table ON code=productCode WHERE listName=:listName")
    fun getProducstForProductList(listName : String) : LiveData<List<Product>>

    @Query("SELECT code, model, pvpr, qtr, segmentation FROM product_table INNER JOIN products_in_productlist_table ON code=productCode WHERE listName=:listName and code=:productCode")
    fun getProductAddedToCertainList(listName : String, productCode: String) : List<Product>
}

实体:

@Entity(
    indices = [Index("productCode")],
    tableName = "products_in_productlist_table",
    primaryKeys = ["listName", "productCode"],
    foreignKeys = [
        ForeignKey( onDelete = ForeignKey.CASCADE,
            entity = ProductList::class,
            parentColumns = ["name"],
            childColumns = ["listName"]),
        ForeignKey( entity = Product::class,
            parentColumns = ["code"],
            childColumns = ["productCode"])
    ]

)
class ProductsInProductList {

    @NonNull
    @ColumnInfo(name = "listName")
    val listName : String

    @NonNull
    @ColumnInfo(name = "productCode")
    val productCode : String

    constructor(listName: String, productCode: String) {
        this.listName = listName
        this.productCode = productCode
    }
}

产品适配器:

private val mInflater = LayoutInflater.from(context)
    private val context = context
    private var mProducts : List<Product>? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
        val itemView = mInflater.inflate(R.layout.product_item, parent, false)
        return ProductViewHolder(itemView)
    }

    fun setProducts(products : List<Product>) {
        this.mProducts = products
    }

    override fun getItemCount(): Int {
        if(mProducts != null)
            return mProducts!!.size
        return 0
    }

    override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
        if(mProducts != null) {
            val current = mProducts!!.get(position)
            holder.setText(current.code)
        } else {
            holder.setText(context.resources.getString(R.string.lbl_no_list_created))
        }
    }

    fun getProductAtPosition(position: Int) : Product {
        return mProducts!!.get(position)
    }

ProductViewHolder:

private var productItemView : TextView = itemView.findViewById(R.id.productItemRecyclerView)

    fun setText(current: String) {
        productItemView.text = current
    }

有人知道为什么在products_in_productlist_table表中创建新行时,LiveData不会被更新吗?

1 个答案:

答案 0 :(得分:0)

在您的AdapterClass中的方法中添加notifyDataSetChange()

fun setProducts(products : List<Product>) {
        this.mProducts = products
        notifyDataSetChange()
    }