我正在创建一个带有回收站视图、卡片视图和 SQLite 数据库的应用程序。卡片视图包含标题、描述和删除图标(在项目单击时)。当用户在卡片视图中输入一些数据时,它会显示在回收器视图中并添加到数据库中。
我想要什么:当我单击卡片视图中的删除图标时,我想同时从数据库和回收站视图中删除所需的卡片视图。
问题:假设我添加了 3 个卡片视图,当我单击其中一个的删除图标时它会消失,但最后添加的卡片视图的副本出现在底部,因此卡片视图的数量保持不变( 3 张卡片)请检查下面的图片。
回收者视图适配器的代码:
class BillsAdapter(val bills: List<Bill>) : RecyclerView.Adapter<BillsAdapter.BillViewHolder>() {
private var mListener: OnItemClickListener? = null
interface OnItemClickListener {
fun onDeleteClick(position: Int)
}
fun setOnClickListener(listener: OnItemClickListener) {
mListener = listener
}
class BillViewHolder( val card: View, listener: OnItemClickListener?) : RecyclerView.ViewHolder(card) {
var mDeleteImage: ImageView
init {
mDeleteImage = card.findViewById(R.id.btn_delete)
mDeleteImage.setOnClickListener {
if (listener != null) {
val position = adapterPosition
if (position != RecyclerView.NO_POSITION) {
listener.onDeleteClick(position)
}
}
}
}
}
override fun onBindViewHolder(holder: BillViewHolder, index: Int) {
val bill = bills[index]
holder.card.tv_title.text = bill.title
holder.card.tv_description.text = bill.description
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BillViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.single_card, parent, false)
return BillViewHolder(view, mListener)
}
override fun getItemCount(): Int = bills.size
数据库处理程序代码:
class billDbHandler (context: Context) : SQLiteOpenHelper(context,
DATABASE_NAME, null, DATABASE_VERSION) {
private val SQL_CREATE_ENTRIES = "CREATE TABLE ${BillEntry.TABLE_NAME} (" +
"${BillEntry._ID} INTEGER PRIMARY KEY," +
"${BillEntry.TITLE_COL} TEXT," +
"${BillEntry.DESCR_COL} TEXT," +
")"
private val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS ${BillEntry.TABLE_NAME}"
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(SQL_CREATE_ENTRIES)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL(SQL_DELETE_ENTRIES)
onCreate(db)
}
}
数据库表代码:
class BillDbTable(context: Context) {
private val TAG = BillDbTable::class.java.simpleName
private val dbHelper = billDbHandler(context)
fun store(bill: Bill): Long {
val db = dbHelper.writableDatabase
val values = ContentValues()
values.put(BillEntry.TITLE_COL, bill.title)
values.put(BillEntry.DESCR_COL, bill.description)
val id = db.insert(BillEntry.TABLE_NAME, null,values)
db.close()
Log.d(TAG, "Stored new bill to DB $bill")
return id
}
fun readAllBills(): List<Bill> {
val columns = arrayOf(BillEntry._ID,
BillEntry.TITLE_COL, BillEntry.DESCR_COL)
val order = "${BillEntry._ID} ASC"
val db= dbHelper.readableDatabase
val cursor = db.doQuery(BillEntry.TABLE_NAME, columns, orderBy = order)
return parseBillsFrom(cursor)
}
fun parseBillsFrom(cursor: Cursor): MutableList<Bill> {
val bills = mutableListOf<Bill>()
while (cursor.moveToNext()) {
val title = cursor.getString(BillEntry.TITLE_COL)
val desc = cursor.getString(BillEntry.DESCR_COL)
bills.add(Bill(title, desc))
}
cursor.close()
return bills
}
fun delete() {
val columns = arrayOf(BillEntry._ID,
BillEntry.TITLE_COL, BillEntry.DESCR_COL)
val order = "${BillEntry._ID} ASC"
val db = dbHelper.writableDatabase
val cursor = db.doQuery(BillEntry.TABLE_NAME, columns, orderBy = order)
if (cursor.moveToNext()){
val id = cursor.getLong(0)
db.delete(BillEntry.TABLE_NAME, BillEntry._ID + "= ?" , arrayOf(id.toString()))
cursor.close()
}
db.close()
} } fun SQLiteDatabase.doQuery(table: String, columns: Array<String>, selection: String? = null,
selectionArgs: Array<String>? = null, groupBy: String? = null,
having: String? = null, orderBy: String? = null): Cursor {
return query(table, columns, selection, selectionArgs, groupBy, having, orderBy)} private fun Cursor.getString(columnName: String): String = this.getString(getColumnIndex(columnName))
主要活动代码:
class MainActivity : AppCompatActivity() {
var db = BillDbTable(this)
private var mAdapter: BillsAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mAdapter = BillsAdapter(db.readAllBills())
rv.setHasFixedSize(true)
rv.layoutManager = LinearLayoutManager(this)
rv.adapter = mAdapter
mAdapter!!.setOnClickListener(object : BillsAdapter.OnItemClickListener {
override fun onDeleteClick(position: Int) {
removeCard(position)
}
})
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.add_bill){
val intent = Intent(this, CreateBillActivity::class.java)
startActivity(intent)
}
return true
}
fun test() {
Toast.makeText(this, "Item Deleted", Toast.LENGTH_LONG).show()
}
fun removeCard(position: Int){
db.delete()
test()
mAdapter!!.notifyItemRemoved(position)
} }
点击所有卡片的删除图标前
有几种可能的策略,这里有两个:
bills
从数据库中删除时从中删除项目来管理存储的项目列表(例如)。您设置适配器的方式是初始化调用者拥有项目列表。适配器修改传递给它的列表通常不是一个好主意,您需要复制到可变集合或重新加载。
在进行移除更改后,您还需要在适配器上调用notifyItemRemoved、notifyItemRangeRemoved或notifyDataSetChanged(取决于您实施移除的方式)。
您可能还想查看DiffUtil。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句