how do i remove row from recyclerview using room?

孤街浪徒 提交于 2020-08-17 07:56:48

问题


I'm trying to delete an row of recyclerview using room.im doing swipe to delete a particular row....

here is my Address table-->

@Entity(tableName = "address")
 class Address {
@PrimaryKey(autoGenerate = true)
var id = 0

@ColumnInfo(name = "address")
var address: String? = null
 }

AddressDao:

@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:

@Database(entities = [Address::class], version = 1)
abstract class Database : RoomDatabase() {
abstract fun AddressDao(): AddressDao
 } 

AddressActivity:

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) }})


    }
}

Adapter:

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
    }

}

From the above code im able delete a row at a moment but when i revisit the activity it shows that deleted row again

i want to know how can i delete a data which is stored in room using in onBindviewHolder

updated code of adapter as @Eishon: suggested

class AddressAdapter(context: Context): RecyclerSwipeAdapter<AddressAdapter.ViewHolder>() {
private var addresses: MutableList<Address> = Collections.emptyList()
 val context: Context
var index = -1
var listener1: ListItemClick? = null

private var lastSelectedPosition = -1


init {
    this.context = context
}

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) {
    viewHolder.radio.setChecked(lastSelectedPosition == position);

    val fl: Address = addresses[position]
    viewHolder.tv.setText(fl.address)

         // context.startActivity(i)

    viewHolder.radio.setOnClickListener(View.OnClickListener {
        lastSelectedPosition = position
        notifyDataSetChanged()
        index = position
        notifyDataSetChanged()
        val intent = Intent("custom-message1")

        intent.putExtra("item1", fl.address)
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent)

        Toast.makeText(
            context,
            "selected offer is " ,
            Toast.LENGTH_LONG
        ).show()
    })
    if (index === position) {
        viewHolder.linearLayout.setBackgroundColor(Color.parseColor("#FF4081"))
    } else {
        viewHolder.linearLayout.setBackgroundColor(Color.parseColor("#FFFFFF"))
    }

    viewHolder.swipelayout.setShowMode(SwipeLayout.ShowMode.PullOut)
    viewHolder.swipelayout.addDrag(
        SwipeLayout.DragEdge.Right,
        viewHolder.swipelayout.findViewById(R.id.bottom_wrapper)
    )
    viewHolder.swipelayout.addSwipeListener(object : SwipeLayout.SwipeListener {
        override fun onClose(layout: SwipeLayout) {
        }

        override fun onUpdate(layout: SwipeLayout, leftOffset: Int, topOffset: Int) {
        }

        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)

        listener1?.onClick(position)


        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.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
    var linearLayout: LinearLayout
    var radio: RadioButton


    init {

        tvDelete=itemView.findViewById(R.id.tvDelete)
        linearLayout =
            itemView.findViewById(R.id.linearlayoutaddressitem)
        /**/radio = itemView.findViewById(R.id.radiobutton)


        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
}
fun updateData1(addresses: MutableList<Address>, listener1:ListItemClick)
{//how should i call this is activity??
    this.addresses = addresses
    this.listener1 = listener1
    notifyDataSetChanged()
}

}

AddressActivity:

class AddressActivity : AppCompatActivity(),ListItemClick {
private lateinit var data: LiveData<MutableList<Address>>
private  var data1:Int = 0
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)
    }
    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
        IntentFilter("custom-message1")
    )
    val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)
    recyclerView.setHasFixedSize(true)
    recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
    val adapter = AddressAdapter(applicationContext)

    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) }})


}
    }
}
override fun onClick(id: Int) {
    val application = application as CustomApplication
    data1 = application.database.AddressDao().deleteAddress(id)
}

}


回答1:


Could you try this:

viewHolder.tvDelete.setOnClickListener(View.OnClickListener { view ->
    // this code is to have access to the database inside adapter you should find another way to do it,
    // like pass database in contructor for ex...
    val application = application as CustomApplication
    Database = application.database.AddressDao()
   // main code to delete in db
   GlobalScope.launch(Dispatchers.IO) {
    Database.delete(addresses[position])
   }
  //

    mItemManger.removeShownLayouts(viewHolder.swipelayout)
    addresses.removeAt(position)
....



回答2:


In Address DAO

@Query("DELETE FROM address WHERE id=:id")
fun deleteAddress(id: Int):Int

then call it from the position where your swipe operation is done.

Update:

Create an Interface like

interface ListItemClick{
    fun onClick(int id)
}

implement on your Address activity class and pass this interface to the Adapter.

fun updateData(addresses:MutableList<Address>, listener:ListItemClick) {
        this.addresses = addresses
        this.listener = listener
        notifyDataSetChanged()
}

then, where you implemented swipe to delete, call

listener.onClick(item_id)

on AddressActivity inside onClick of ListItemClick interface

val application = application as CustomApplication
data = application.database.AddressDao().deleteAddress(id)

I wrote it here, so some spelling mistake may remain. But,I think you got the basic idea.



来源:https://stackoverflow.com/questions/63266686/how-do-i-remove-row-from-recyclerview-using-room

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!