【发布时间】:2020-08-05 13:52:49
【问题描述】:
我正在尝试使用 room.im 删除一行 recyclerview 进行滑动以删除特定行....
这是我的地址表-->
@Entity(tableName = "address")
class Address {
@PrimaryKey(autoGenerate = true)
var id = 0
@ColumnInfo(name = "address")
var address: String? = null
}
地址道:
@Dao
interface AddressDao {
@Insert
suspend fun addData(address: Address)
@Query("select * from address")
fun getAddressesWithChanges() :LiveData<MutableList<Address>>
@Query("SELECT EXISTS (SELECT 1 FROM address WHERE id=:id)")
suspend fun isAddressAdded(id: Int): Int
@Delete
suspend fun delete(address: Address)
}
数据库:
@Database(entities = [Address::class], version = 1)
abstract class Database : RoomDatabase() {
abstract fun AddressDao(): AddressDao
}
地址活动:
class AddressActivity : AppCompatActivity() {
private val adapter = AddressAdapter()
private lateinit var data: LiveData<MutableList<Address>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.address)
addbutton.findViewById<View>(R.id.addbutton).setOnClickListener {
val intent = Intent(this, AddAddressActivity::class.java)
startActivity(intent)
}
val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = adapter
recyclerView.addItemDecoration(DividerItemDecorator(resources.getDrawable(R.drawable.divider)))
recyclerView.addOnScrollListener(object :
RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
Log.e("RecyclerView", "onScrollStateChanged")
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
}
})
val application = application as CustomApplication
data = application.database.AddressDao(). getAddressesWithChanges()
data.observe(this, Observer { words1 ->
// Update the cached copy of the words in the adapter.
words1?.let { adapter.updateData(it) }})
}
}
适配器:
class AddressAdapter: RecyclerSwipeAdapter<AddressAdapter.ViewHolder>() {
private var addresses: MutableList<Address> = Collections.emptyList()
lateinit var Database:Database
override fun onCreateViewHolder(viewGroup: ViewGroup, itemViewType: Int): ViewHolder =
ViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.address_item, viewGroup, false))
override fun getSwipeLayoutResourceId(position: Int): Int {
return R.id.swipe;
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
val fl: Address = addresses[position]
viewHolder.tv.setText(fl.address)
viewHolder.swipelayout.setShowMode(SwipeLayout.ShowMode.PullOut)
// Drag From Right
// Drag From Right
viewHolder.swipelayout.addDrag(
SwipeLayout.DragEdge.Right,
viewHolder.swipelayout.findViewById(R.id.bottom_wrapper)
)
// Handling different events when swiping
viewHolder.swipelayout.addSwipeListener(object : SwipeLayout.SwipeListener {
override fun onClose(layout: SwipeLayout) {
//when the SurfaceView totally cover the BottomView.
}
override fun onUpdate(layout: SwipeLayout, leftOffset: Int, topOffset: Int) {
//you are swiping.
}
override fun onStartOpen(layout: SwipeLayout) {}
override fun onOpen(layout: SwipeLayout) {
}
override fun onStartClose(layout: SwipeLayout) {}
override fun onHandRelease(
layout: SwipeLayout,
xvel: Float,
yvel: Float
) {
}
})
viewHolder.tvDelete.setOnClickListener(View.OnClickListener { view ->
mItemManger.removeShownLayouts(viewHolder.swipelayout)
addresses.removeAt(position)
//What should i do here??????????????????????????
// val address = Address()
// Database.AddressDao().delete(address)
notifyDataSetChanged()
notifyItemRemoved(position)
notifyItemRemoved(position)
notifyItemRangeChanged(position, addresses.size)
mItemManger.closeAllItems()
Toast.makeText(
view.context,
"Deleted " + viewHolder.tv.getText().toString(),
Toast.LENGTH_SHORT
).show()
})
// mItemManger is member in RecyclerSwipeAdapter Class
// mItemManger is member in RecyclerSwipeAdapter Class
mItemManger.bindView(viewHolder.itemView, position)
}
override fun getItemCount(): Int = addresses.size
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tv: TextView
val swipelayout: SwipeLayout
val tvDelete:TextView
init {
tvDelete=itemView.findViewById(R.id.tvDelete)
tv = itemView.findViewById(R.id.ftv_name)
swipelayout=itemView.findViewById(R.id.swipe)
} }
fun updateData(addresses:
MutableList<Address>) {
this.addresses = addresses
notifyDataSetChanged() // TODO: use ListAdapter if animations are needed
}
}
从上面的代码中,我可以一次删除一行,但是当我重新访问该活动时,它会再次显示已删除的行
我想知道如何使用onBindviewHolder删除存储在房间中的数据
根据@quealegriamasalegre 建议的最新答案
这是我的自定义应用程序:--
class CustomApplication: Application() {
lateinit var database: Database
private set
lateinit var addressDao: AddressDao
private set
override fun onCreate() {
super.onCreate()
this.database = Room.databaseBuilder<Database>(
applicationContext,
Database::class.java, "database"
).build()
addressDao = database.AddressDao()
}
}
现在适配器:
viewHolder.tvDelete.setOnClickListener(View.OnClickListener { view ->
mItemManger.removeShownLayouts(viewHolder.swipelayout)
addresses.removeAt(position)
val application = CustomApplication()
application.database.AddressDao().deleteAddress(position)//here you delete from DB so its gone for good
//notifyDataSetChanged() dont do this as it will reexecute onbindviewholder and skip a nice animation provided by android
//notifyItemRemoved(position) execute only once
notifyDataSetChanged()
notifyItemRemoved(position)
notifyItemRemoved(position)
notifyItemRangeChanged(position, addresses.size)
mItemManger.closeAllItems()
Toast.makeText(
view.context,
"Deleted " + viewHolder.tv.getText().toString(),
Toast.LENGTH_SHORT
).show()
})
现在因 kotlin.UninitializedPropertyAccessException 崩溃:lateinit 属性数据库尚未初始化
真的需要帮助....
【问题讨论】:
-
您不必这样做:val application = CustomApplication()(它是由 Android 初始化的核心实例)。将您的 applicationContext 转换为 CustomApplication 并访问数据库。
-
我应该怎么做 -->
Cast your applicationContext to CustomApplication@MaximFirsoff 在适配器中? -
@MaximFirsoff 如果我这样做 -->
val application = context as CustomApplication我得到错误-->java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. -
是的,没错,数据库访问应该在后台线程中使用。
标签: android android-recyclerview android-room android-livedata delete-row