一、前言:
在最近的学习中,使用Recyclerview控件时,遇到需要长按删除的场景,在测试过程中,遇到各种崩溃,在这里总结一下:
在本博客汇中,使用了一个统计学生信息的demo,并且用到了SQLite,这样保证长按删除的同时数据库也能同步数据,先上一下长按删除的效果图:
二、代码分析:
长按删除item最重要的是要确保数据库的同步进行。
1.Student类代码:
class Student(val name: String, val gender: String, val age: Int) {
2.数据库代码:
package com.example.recyclerlongclickremove
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.widget.Toast
class StudentBaseHelper(val context: Context, val name: String, val versin: Int) :
SQLiteOpenHelper(context, name, null, versin) {
private val createStockData = "create table $name (" +
"id integer primary key autoincrement, " +
"studentName text," +
"gender text," +
"age INTEGER)"
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(createStockData)
Toast.makeText(context, "Create $name succeeded", Toast.LENGTH_LONG).show()
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
Toast.makeText(context, "upgrade $name succeeded", Toast.LENGTH_LONG).show()
db.execSQL("drop table if exists $name")
onCreate(db)
这里面只实现了两个必须要覆写的函数;
3.数据库操作的封装代码:
package com.example.recyclerlongclickremove
import android.content.ContentValues
import android.content.Context
class StudentBaseControl(val context: Context, val name: String, val version: Int) {
private var dbHelper = StudentBaseHelper(context, name, version)
fun create(){
dbHelper.writableDatabase
fun addData(student: Student){
val db = dbHelper.writableDatabase
val value = ContentValues().apply {
put("studentName", student.name)
put("gender", student.gender)
put("age", student.age)
db.insert(name, null, value)
* 遍历全局数据库
fun queryAllData(name: String) : ArrayList<Student>{
val db = dbHelper.writableDatabase
val dataList = ArrayList<Student>()
val cursor = db.query(name, null,
null, null, null,
null, null, null)
if (cursor.moveToFirst()){
do {
val name = cursor.getString(cursor.getColumnIndex("studentName"))
val gender = cursor.getString(cursor.getColumnIndex("gender"))
val age = cursor.getString(cursor.getColumnIndex("age")).toInt()
dataList.add(Student(name, gender, age))
} while (cursor.moveToNext())
cursor.close()
return dataList
cursor.close()
return dataList
fun deleteData(studentName: String){
val db = dbHelper.writableDatabase
db.delete(name, "studentName = ?", arrayOf(studentName))
create方法,创建数据库,直接操作SQLite;
addData方法,往数据库中添加item;
queryAllData方法,遍历数据库,这个方法的作用主要是用在Activity启动的时候检测是否创建了数据库;
deleteData方法,删除数据库中的数据;
4.RecyclerView的适配器:
package com.example.recyclerlongclickremove
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
class StudentsAdapter(list: ArrayList<Student>):
RecyclerView.Adapter <StudentsAdapter.ViewHolder>(){
private var studentList = ArrayList<Student>()
init {
studentList = list
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view){
val name : TextView = view.findViewById(R.id.name)
val gender : TextView = view.findViewById(R.id.gender)
val age : TextView = view.findViewById(R.id.age)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.student, parent, false)
val viewHolder = ViewHolder(view)
viewHolder.itemView.setOnClickListener {
Toast.makeText(parent.context, "you click outer item!",
Toast.LENGTH_SHORT).show()
* 长按监听:删除item
viewHolder.itemView.setOnLongClickListener {
val position = viewHolder.adapterPosition
Log.d("jiyi", "adapter remove:${studentList[position].name}")
MainActivity.mainActivityTodo(
MainActivity.HANDLELONGCLIECK,
studentList[position].name)
studentList.remove(studentList[position])
notifyItemRemoved(position)
notifyItemRangeChanged(position, studentList.size)
false
return viewHolder
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val student = studentList[position]
holder.name.text = student.name
holder.gender.text = student.gender
holder.age.text = student.age.toString()
override fun getItemCount() = studentList.size
adapter的基本操作就不说了,我们主要看其中的长按监听删除item事件:
我们能将数据库中的数据显示到控件上,是使用了ArrayList的,而数据又是从数据库中来的,因此,在删除事件的处理上,这两个地方都要进行各自数据的删除,Arraylist的删除操作就由adapter来完成,数据库的删除操作由MainActivity来完成,所以在代码中可以看到,这里借助了MainActivity提供的静态方法,将需要删除的学生名字给传递过去,当然,这里是为了方便,学生名字都没有重复,在实际开发中,你肯定有自己的数据删选准则,删除ArrayList就只需要调用remove就好了,notifyItemRemoved方法则是为了通知adapter,进行UI上的刷新,代码中还有一句notifyItemRangeChanged,我实测中发现这句有没有并没有什么区别,但网上有人说需要这句,所以我还是保留了,总的来说,adapter的主要操作是删除ArrayList中的数据,剩下的就交给MainActivity了;
5.MainAcrtivity的实现:
package com.example.recyclerlongclickremove
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
import kotlin.concurrent.thread
internal var onLongClickFlag = false
internal var removeStudentName = ""
class MainActivity : AppCompatActivity() {
private var threadRun = true
private var studentList = ArrayList<Student>()
val databaseStudent = StudentBaseControl(this, "Student", 1)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
* 将当前活动赋值给静态对象
mainActivity = this
* 如果数据库不存在:创建 + 添加初始数据
if (databaseStudent.queryAllData("Student").size == 0){
databaseStudent.create()
* 初始化student数据
initStudent()
for (i in 0 until (studentList.size)){
databaseStudent.addData(studentList.get(index = i))
override fun onResume() {
super.onResume()
* 重新填充studentList数据,避免从其他activity回来之后数据有改变
studentList.clear()
studentList = databaseStudent.queryAllData("Student")
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
val adapter = StudentsAdapter(studentList)
recyclerView.adapter = adapter
thread {
while (threadRun){
if (onLongClickFlag){
if (removeStudentName != ""){
databaseStudent.deleteData(removeStudentName)
onLongClickFlag = false
removeStudentName = ""
Thread.sleep(200)
private fun initStudent(){
repeat(1){
studentList.add(Student("张三", "男", 27))
studentList.add(Student("李四", "女", 28))
studentList.add(Student("王五", "男", 29))
studentList.add(Student("赵六", "女", 30))
studentList.add(Student("郭七", "男", 31))
* MainActivity的单实例,用于供外部类调用的static方法等
companion object{
const val HANDLELONGCLIECK = "handlelongclick"
lateinit var mainActivity : AppCompatActivity
* mainActivityTodo由外部类回调MainActivity操作
* event:需要执行的操作
* stockCode:响应控件对应的股票代码
@JvmStatic
fun mainActivityTodo(event: String, studentName: String){
when (event){
HANDLELONGCLIECK -> {
onLongClickFlag = true
removeStudentName = studentName
Log.d("MainActivity", "remove student:$studentName")
为了方面监测用户是否是删除了item,在MainActivity中我跑了一个线程,如果确认有长按删除事件触发时,onLongClickFlag这个布尔值会置为true,那么,只需要这时调用deleteData删除数据库中的数据就可以了;
三、总结:
RecyclerView的长按删除事件调用setOnLongClickListener就可以了,只不过在实际中,一定要区别处理ArrayList和SQLite中的操作,不然很容易出现各种崩溃的问题。
一、前言:在最近的学习中,使用Recyclerview控件时,遇到需要长按删除的场景,在测试过程中,遇到各种崩溃,在这里总结一下:在本博客汇中,使用了一个统计学生信息的demo,并且用到了SQLite,这样保证长按删除的同时数据库也能同步数据,先上一下长按删除的效果图:二、代码分析:长按删除item最重要的是要确保数据库的同步进行。1.Student类代码:class Student(val name: String, val gender: String, val age: Int) {}
ButterKnife:
1. 在project下的build.gradle中粘贴以下代码
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
2.在app下的build.gradle中粘贴以下代码
粘贴在最上面 :
RecyclerView是Android
5.x版本中新添加的一个全新控件,他比ListView,GridView更加的灵活,我们能够使用RecyclerView就完成ListView,GridView所做的工作,同时使用RecyclerView也能非常方便的实现瀑布流的效果。
一.竖屏ListView,横屏GridView效果
MainActivity代码:
public class
上篇文章介绍了RecyclerView控件的基本用法,我们已经知道它是一个ListView的升级版,可轻松的展示各种列表风格,例如水平列表、垂直列表、网格列表、瀑布流列表等。但是,我们项目中仅仅展示数据是不够的,我们经常还有列表项的单击事件、添加列表项、删除列表项等。今天我们就着重讲解一下RecyclerView列表项的单击事件、添加列表项、删除列表项。
1.Recy...
在项目开发中常常会遇到这种需求,自己写吧 水平不够,自定义view绘制不是太好.多番查找资料和网上百度以后,终于实现了效果,废话不说了,看代码.
第一步:这是一个工具类代码较多:建议粘贴
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.Nullable;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.OneAdapter> implements View.OnClickListener {
Contex...
MainActivitypackage com.bwie.recyclerview_practice2;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.suppo
Android中使用kotlin开发RecyclerView:
提示:这里简述项目相关背景:
RecyclerView是Android中经常使用的控件,接下来就是对RecyclerView使用方法的一些讲解
提示:我在Androidstudio中使用了 ViewBinding
在build.gradle(app)的android中加入以下代码
buildFeatures
viewBinding = true
在MyApplication中使用:
@Over
问题:想要实现recycleview长按后显示删除图标,但是仅仅能实现当前item删除图标的显示,无法实现所有的item都出现删除图标,错误实现的逻辑是直接在itemView长按事件里面这个改变图片的显示与隐藏状态,这里仅能实现当前item删除图标的显示,所以是行不通的!我这里的代码背景是使用room数据库存数据,然后读取使用recycleview显示,然后在长按,所有的item显示删除图标。本文就记录一下这个问题,增加自己的记忆。
下面就说一下实现逻辑以及部分代码
第一步在RecycleView的adap