Recycler中的checkbox勾选为true时,查看项目被immedietaly选中为false

我使用RxJava2,Kotlin和Room作为例子。

以下是将我的项目填充到recyclerView的适配器:

class ShoppingListDetailsAdapter(val list: ArrayList, val context: Context, val listener: ShoppingItemCheckboxListener, val isArchived: Boolean) : RecyclerView.Adapter() { override fun getItemCount(): Int { return list.count() } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder { val itemView = LayoutInflater.from(parent?.getContext()) .inflate(R.layout.item_shopping_list_element, parent, false) return ViewHolder(itemView) } override fun onBindViewHolder(holder: ViewHolder?, position: Int) { val item = list.get(position) holder?.name?.setText(item.name) if(item.isCompleted){ holder?.isCompleted?.isChecked = true } if(isArchived) holder?.isCompleted?.isEnabled = false else{ holder?.isCompleted?.isEnabled = true } holder?.isCompleted?.setOnCheckedChangeListener{ buttonView, isChecked -> item.isCompleted = isChecked listener.onClick(position, isChecked) } } inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { var name: TextView var isCompleted: CheckBox private var viewClickListener: ShoppingItemCheckboxListener? = null init { name = view.findViewById(R.id.itemName) isCompleted = view.findViewById(R.id.checkbox) } } fun removeItem(position: Int) { list.removeAt(position) // notify the item removed by position // to perform recycler view delete animations // NOTE: don't call notifyDataSetChanged() notifyItemRemoved(position) } fun restoreItem(item: ShoppingListElementItem, position: Int) { list.add(position, item) // notify item added by position notifyItemInserted(position) } } 

这是我的ViewModel:

 class ShoppingListViewModel(private val dataSource: ShoppingListDao) : ViewModel() { fun createShoppingList(listName: String){ val arrayList = ArrayList() val shoppingList = ShoppingList(name = listName, isArchived = false, items = arrayList, timestamp = Date()) dataSource.insertShoppingList(shoppingList) } fun createShoppingListItem(itemName: String, shoppingListId: Int){ dataSource.getShoppingList(shoppingListId) .firstElement() .subscribe { shoppingList: ShoppingList -> val items = shoppingList.items items.add(ShoppingListItem(itemName, false, Date())) dataSource.updateShoppingList(shoppingList = shoppingList) } } fun getShoppingLists(): Flowable<List> { return dataSource.getActiveShoppingLists() .map { t -> t.sortedByDescending { it.timestamp } } } fun getArchivedLists(): Flowable<List> { return dataSource.getArchivedShoppingLists() .map { t -> t.sortedByDescending { it.timestamp } } } fun getShoppingList(id: Int): Flowable { return dataSource.getShoppingList(id) } fun archiveItem(deletedShoppingListItem: com.app.shoppinglistapp.ui.ShoppingListDTO) { dataSource.archiveShoppingList(deletedShoppingListItem.id) } fun reArchiveItem(deletedShoppingListItem: com.app.shoppinglistapp.ui.ShoppingListDTO){ dataSource.reArchiveShoppingList(deletedShoppingListItem.id) } fun removeShoppingListItem(deletedItem: ShoppingListElementItem, shoppingListId: Int) { dataSource.getShoppingList(shoppingListId) .firstElement() .subscribe { shoppingList: ShoppingList -> val items: ArrayList = shoppingList.items val filter = items.filter { it.timestamp != deletedItem.timestamp } dataSource.updateShoppingList(shoppingList = ShoppingList(id = shoppingList.id, name = shoppingList.name, isArchived = shoppingList.isArchived, timestamp = shoppingList.timestamp, items = filter as ArrayList )) } } fun restoreShoppingListItem(deletedItem: ShoppingListElementItem, shoppingListId: Int) { dataSource.getShoppingList(shoppingListId) .firstElement() .subscribe { shoppingList: ShoppingList -> val items = shoppingList.items items.add(ShoppingListItem(deletedItem.name, deletedItem.isCompleted, deletedItem.timestamp)) dataSource.updateShoppingList(shoppingList = ShoppingList(id = shoppingList.id, name = shoppingList.name, isArchived = shoppingList.isArchived, timestamp = shoppingList.timestamp, items = items )) } } fun updateShoppingList(shoppingList: ArrayList, shoppingListId: Int) { dataSource.getShoppingList(shoppingListId) .firstElement() .subscribe { t: ShoppingList -> val dbShoppingList = ArrayList() shoppingList.forEach { it -> dbShoppingList.add(ShoppingListItem(it.name, it.isCompleted, it.timestamp)) } dataSource.updateShoppingList(shoppingList = ShoppingList(id = t.id, name = t.name, isArchived = t.isArchived, timestamp = t.timestamp, items = dbShoppingList )) } } } 

这是我的Dao界面:

 @Dao interface ShoppingListDao { @Query("SELECT * FROM shopping_list where id = :id limit 1") fun getShoppingList(id: Int): Flowable @Query("SELECT * FROM shopping_list where not is_archived") fun getActiveShoppingLists(): Flowable<List> @Query("SELECT * FROM shopping_list where is_archived") fun getArchivedShoppingLists(): Flowable<List> @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertShoppingList(shoppingList: ShoppingList) @Update fun updateShoppingList(shoppingList: ShoppingList) @Query("UPDATE shopping_list SET is_archived = 1 where id = :id") fun archiveShoppingList(id: Int) @Query("UPDATE shopping_list SET is_archived = 0 where id = :id") fun reArchiveShoppingList(id: Int) } 

这里是活动:

 class ShoppingListDetailsActivity : AppCompatActivity(), RecyclerItemTouchHelper.RecyclerItemTouchHelperListener, ShoppingItemCheckboxListener { private lateinit var viewModelFactory: ViewModelFactory private lateinit var viewModel: ShoppingListViewModel private var intExtra: Int? = null private var isArchived: Boolean? = null private val disposable = CompositeDisposable() private var shoppingList = ArrayList() private var mAdapter: ShoppingListDetailsAdapter? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) setSupportActionBar(toolbar) supportActionBar!!.setDisplayHomeAsUpEnabled(true) intExtra = getIntent().getIntExtra("id", 0) isArchived = getIntent().getBooleanExtra("isArchived", false) viewModelFactory = Injection.provideViewModelFactory(this) viewModel = ViewModelProviders.of(this, viewModelFactory).get(ShoppingListViewModel::class.java) // mAdapter = ShoppingListDetailsAdapter(shoppingList, this, this, isArchived!!) val mLayoutManager = LinearLayoutManager(applicationContext) recyclerView.setLayoutManager(mLayoutManager) recyclerView.setItemAnimator(DefaultItemAnimator()) recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL)) // recyclerView.setAdapter(mAdapter) if (isArchived as Boolean) { fab.visibility = View.GONE } else{ fab.setOnClickListener { view -> val alertDialogAndroid = getShoppingListDialog() alertDialogAndroid?.show() } } val itemTouchHelperCallback1 = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) { override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { // Row is swiped from recycler view // remove it from adapter if (viewHolder is ShoppingListDetailsAdapter.ViewHolder) { // get the removed item name to display it in snack bar val name = shoppingList[viewHolder.adapterPosition].name // backup of removed item for undo purpose val deletedItem = shoppingList[viewHolder.adapterPosition] val deletedIndex = viewHolder.adapterPosition // remove the item from recycler view mAdapter?.removeItem(viewHolder.adapterPosition) viewModel.removeShoppingListItem(deletedItem, intExtra!!) // showing snack bar with Undo option val snackbar = Snackbar .make(coordinatorLayout, name + " is deleted!", Snackbar.LENGTH_LONG) snackbar.setAction("UNDO", View.OnClickListener { // undo is selected, restore the deleted item mAdapter?.restoreItem(deletedItem, deletedIndex) viewModel.restoreShoppingListItem(deletedItem, intExtra!!) }) snackbar.setActionTextColor(Color.YELLOW) snackbar.show() } Log.v("Test", "test") } override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) { super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) } } if (!isArchived!!) ItemTouchHelper(itemTouchHelperCallback1).attachToRecyclerView(recyclerView) } fun getShoppingListDialog(): AlertDialog? { val layoutInflaterAndroid = LayoutInflater.from(this) val mView = layoutInflaterAndroid.inflate(R.layout.dialog_input_name, null) val alertDialogBuilderUserInput = AlertDialog.Builder(this) alertDialogBuilderUserInput.setView(mView) val userInputDialogEditText = mView.findViewById(R.id.userInputDialog) as EditText alertDialogBuilderUserInput .setCancelable(false) .setPositiveButton("Send", DialogInterface.OnClickListener { dialogBox, id -> viewModel.createShoppingListItem(userInputDialogEditText.text.toString(), intExtra!!) }) .setNegativeButton("Cancel", DialogInterface.OnClickListener { dialogBox, id -> dialogBox.cancel() }) return alertDialogBuilderUserInput.create() } override fun onSupportNavigateUp(): Boolean { onBackPressed() return true } override fun onStart() { super.onStart() if (intExtra != null) viewModel.getShoppingList(intExtra!!) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ t -> shoppingList.clear() t.items.forEach { val item = ShoppingListElementItem(0, it.name, false, it.timestamp) shoppingList.add(item) } shoppingList.size mAdapter = ShoppingListDetailsAdapter(shoppingList, this, this, isArchived!!) recyclerView.setAdapter(mAdapter) // mAdapter?.notifyDataSetChanged() }) } override fun onStop() { super.onStop() // clear all the subscription disposable.clear() } override fun onClick(position: Int, isChecked: Boolean) { shoppingList.get(position).isCompleted = isChecked viewModel.updateShoppingList(shoppingList, intExtra!!) Toast.makeText(applicationContext, "isChecked: ${isChecked}", Toast.LENGTH_SHORT).show() } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int, position: Int) { } } 

当我试图检查我的RecyclerView项目中的checbox它immedietaly被检查为false然后。

这是模型实体:

 @Entity(tableName = "shopping_list") data class ShoppingList( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int = 0, @ColumnInfo(name = "name") val name: String, @ColumnInfo(name = "is_archived") val isArchived: Boolean, @ColumnInfo(name = "timestamp") val timestamp: Date, @ColumnInfo(name = "items") val items: ArrayList ) data class ShoppingListItem( val name: String, val isCompleted: Boolean, val timestamp: Date ) 

而购物清单项目的布局:

      

和ShoppingListElementItem类:

 data class ShoppingListElementItem( var id: Int, var name: String, var isCompleted: Boolean, val timestamp: Date ) 

听众:

 interface ShoppingItemCheckboxListener { fun onClick(position: Int, isChecked: Boolean) } 

当我试图检查我的RecyclerView项目中的checkbox,它immedietaly被检查回false。 在更新checkbox后,我的Acitivty订阅方法,从数据库获取更新的项目被正确设置为检查(“isCompleted”),但我想我的适配器设置错误。 在我的onBindViewHolder方法中,被设置为检查的项目始终是false,所以我想它没有正确更新适配器列表项目。

如何使其正常工作?

UPDATE

即使当我重新启动应用程序,checkbox没有设置为true,但从数据库获取的项目具有属性“isCompleted”设置为true。 问题是在适配器真的,我不知道为什么它没有我期望的项目 – 在我的订阅方法中,我正在提取项目被填充到适配器,他们是正确的。

你可以检查这个function吗?

 override fun onStart() { super.onStart() if (intExtra != null) viewModel.getShoppingList(intExtra!!) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ t -> shoppingList.clear() t.items.forEach { val item = ShoppingListElementItem(0, it.name, false, it.timestamp) shoppingList.add(item) } shoppingList.size mAdapter = ShoppingListDetailsAdapter(shoppingList, this, this, isArchived!!) recyclerView.setAdapter(mAdapter) // mAdapter?.notifyDataSetChanged() }) 

在这个函数中,您正在订购可流动的购物清单,这意味着只要有数据库更新,这个订阅方法就会被调用,下面的代码将把完成的值重置为false

 ShoppingListElementItem(0, it.name, false, it.timestamp) 

我认为问题在于这个代码块

  holder?.isCompleted?.setOnCheckedChangeListener{ buttonView, isChecked -> item.isCompleted = isChecked listener.onClick(position, isChecked) } 

当你点击checkbox时, isChecked为true,如果我没有弄错, listener.onClick(position,isChecked)单击RecyclerView的同一个项目。 ShoppingItemCheckboxListener做什么的?