Мой проект в основном позволяет пользователю создавать список продуктов, в которые могут быть добавлены различные продукты. Так что в моем случае отношение между моими сущностями много-много: у меня есть таблица для всех продуктов, которые добавляются при установке приложения, у меня есть таблица со списками, которые создает пользователь, и, наконец, у меня есть таблица, которая регистрирует, когда пользователь добавляет товар в список.
Проблема, которую я получаю, заключается в том, что после добавления пользователем продукта в список данные 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 не обновляется?