Kotlin: Remove list in Recycerview using AlertDialog button - kotlin

I hope to remove items in Recyclerview by AlertDialog button.
Do you have idea?
Adapter & Viewholer
class ProjectsRecyclerAdapter(val list:List<ProjectListDataModel>, var clickListner: OnProjectListClickListner) : RecyclerView.Adapter<ProjectRecyclerViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProjectRecyclerViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_cardview, parent, false)
return ProjectRecyclerViewHolder(
view
)
}
override fun getItemCount(): Int {
return list.count()
}
override fun onBindViewHolder(holder: ProjectRecyclerViewHolder, position: Int) {
holder.initialize(list[position], clickListner)
}
}
class ProjectRecyclerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun initialize(item: ProjectListDataModel, action: OnProjectListClickListner) {
itemView.projectNameText.text = item.name
itemView.modifiedTimeText.text = item.modTime
itemView.descriptionText.text = item.description
itemView.setOnClickListener {
action.onItemClick(item, adapterPosition)
}
}
}
interface OnProjectListClickListner {
fun onItemClick(item: ProjectListDataModel, position: Int)
}
And here is Main Activity
class LocalProjectListActivity :
AppCompatActivity(),
OnProjectListClickListner,
NavigationView.OnNavigationItemSelectedListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
val localProjectList = listOf(
ProjectListDataModel(
"Project A",
"Sun, 01/DEC/2020, 22:23GMT",
"Testing 1",
"AAAA",
"A, A",
8,
232
),
ProjectListDataModel(
"Project B",
"Sun, 01/JUL/2020, 10:23GMT",
"Testing 2",
"BBBB",
"B, B",
6,
354
),
ProjectListDataModel(
"Project C",
"Sun, 11/MAR/2020, 08:31GMT",
"Testing 3",
"CCCC",
"C,C",
15,
632
)
)
val adapter = ProjectsRecyclerAdapter(localProjectList, this)
projectNameText.adapter = adapter
projectNameText.setHasFixedSize(true)
projectNameText.layoutManager = LinearLayoutManager(this)
}
override fun onItemClick(item: ProjectListDataModel, position: Int) {
val builder = AlertDialog.Builder(this)
val ad = builder.create()
val dialogView = layoutInflater.inflate(R.layout.project_onclick, null)
dialogView.projectNameText.text = item.name
dialogView.modifiedTimeText.text = item.modTime
dialogView.descriptionText.text = item.description
dialogView.fileNumberText.text = item.fileNumber.toString() + "EA"
dialogView.fileSizeText.text = item.fileSize.toString() + "MB"
dialogView.scopeText.text = item.scope
dialogView.userIdText.text = item.resposible
ad.setView(dialogView)
ad.show()
//when click Load button
dialogView.loadButton.setOnClickListener {
ad.dismiss()
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Question1")
dialog.setMessage("You want to go to the project?")
dialog.setPositiveButton("Yes", DialogInterface.OnClickListener { _, _ ->
})
dialog.setNegativeButton("No", DialogInterface.OnClickListener { _, _ ->
val fileFilterIntent = Intent(this, ProjectFileActivity::class.java)
startActivity(fileFilterIntent)
})
dialog.setNeutralButton("Cancel", DialogInterface.OnClickListener {dialog, _ ->
dialog.dismiss()
})
//if(isMarker == true) {
dialog.show()
//} else {}
}
dialogView.deleteButton.setOnClickListener {
ad.dismiss()
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Delet project list")
dialog.setMessage("You want to delete project?")
dialog.setPositiveButton("Yes", DialogInterface.OnClickListener { _, _ ->
**//Delete items in RecyclerView**
})
dialog.setNeutralButton("Cancel", null)
dialog.show()
}
dialogView.cancleButton.setOnClickListener { ad.dismiss() }
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.remoteProjects -> {
val serverProjIntent = Intent(this, ServerProjectListActivity::class.java)
startActivity(serverProjIntent)
}
R.id.settings -> {
Toast.makeText(this, "Go to Settings", Toast.LENGTH_SHORT).show()
}
}
mainLocal.closeDrawer(GravityCompat.START)
return true
}
}
I posted all the code like that.
I can get the lists using Recyclerview, and made the AlertDialog But I don't know how to delete the items using the "Yes" button in AlertDialog.
Please give me some advises.

You'll need to have a reference to the list and the adapter outside of onCreate
private val localProjectList = mutableListOf(
ProjectListDataModel(
"Project A",
"Sun, 01/DEC/2020, 22:23GMT",
"Testing 1",
"AAAA",
"A, A",
8,
232
),
ProjectListDataModel(
"Project B",
"Sun, 01/JUL/2020, 10:23GMT",
"Testing 2",
"BBBB",
"B, B",
6,
354
),
ProjectListDataModel(
"Project C",
"Sun, 11/MAR/2020, 08:31GMT",
"Testing 3",
"CCCC",
"C,C",
15,
632
)
)
private lateinit var adapter: ProjectsRecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
adapter = ProjectsRecyclerAdapter(localProjectList, this)
projectNameText.adapter = adapter
projectNameText.setHasFixedSize(true)
projectNameText.layoutManager = LinearLayoutManager(this)
}
And then delete the list and notify the adapter
private fun deleteItemsAndNotifyAdapter() {
localProjectList.clear()
adapter.notifyDataSetChanged()
}
You can delete and notify adapter in you dialog:
private var alertDialog: AlertDialog? = null
private fun showDeleteDialog() {
val builder = AlertDialog.Builder(activity)
builder.run {
setTitle("Delete project list")
setMessage("You want to delete project?")
setPositiveButton("Yes") { _, _ ->
deleteItemsAndNotifyAdapter()
}
setNegativeButton("Cancel") { _, _ ->
}
}
alertDialog = builder.create()
alertDialog?.show
}

Related

how do i update items that change in recyclerview use diffutil?

DiffUtil do not update items recyclerview with the same id and not same the content,
The model has [id : Int and title : String]. I want to the diffUtilCallBack check items with the same id and not same title and update to recyclerview
Please help me fix it
my DiffUtil CallBAck
class DiffCB(
val oldl : ArrayList<Test>,
val newl : ArrayList<Test>
) : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldl.size
}
override fun getNewListSize(): Int {
return newl.size
}
override fun areItemsTheSame(oldItemPos: Int, newItemPos: Int): Boolean {
return oldl[oldItemPos].id == newl[newItemPos].id
}
override fun areContentsTheSame(oldItemPos: Int, newItemPos: Int): Boolean {
return oldl[oldItemPos].title.equals(newl[newItemPos].title)
}
}
my Adapter.kt
class TestAdapter(val click: TestClick) :
RecyclerView.Adapter<TestAdapter.TestVH>() {
var list: ArrayList<Test> = ArrayList()
inner class TestVH(val bin: ItemTestBinding) : RecyclerView.ViewHolder(bin.root) {
fun bind(test: Test) {
bin.tvTestId.text = "[id: ${test.id}]"
bin.tvTestTitle.text = test.title
bin.cbTest.isChecked = test.select
bin.cbTest.setOnClickListener {
click.click(test)
}
}
}
fun sumbitData(newl: ArrayList<Test>) {
val diff = DiffCB(this.list, newl)
val diffResult = DiffUtil.calculateDiff(diff)
list.clear()
this.list.addAll(newl)
diffResult.dispatchUpdatesTo(this)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: TestVH, position: Int) {
holder.bind(list[position])
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestVH {
return TestVH(ItemTestBinding.inflate(LayoutInflater.from(parent.context),
parent, false))
}
}
my Activity.kt
class TestActivity : AppCompatActivity(), TestClick {
private var list : ArrayList<Test> = ArrayList()
private lateinit var bin : ActivityTestBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bin = ActivityTestBinding.inflate(layoutInflater)
setContentView(bin.root)
val viewModel = ViewModelProviders.of(this).get(TestViewModel::class.java)
val manager = LinearLayoutManager(this)
bin.rvTest.layoutManager = manager
val adapter = TestAdapter(this)
bin.rvTest.adapter = adapter
//init first data
viewModel.setTests(initData())
viewModel.getTests().observe(this, Observer {
adapter.sumbitData(it as ArrayList<Test>)
})
bin.btnTest.setOnClickListener{
viewModel.setTests(updateData())
}
}
fun updateData() : ArrayList<Test> {
for (i in 2..6) {
var test = Test()
test.id = i
test.title = "title test $i update"
list.add(test)
}
return list
}
fun initData() : ArrayList<Test> {
for (i in 1..3) {
var test = Test()
test.id = i
test.title = "title test $i"
list.add(test)
}
return list
}
override fun click(test: Test) {
Toast.makeText(this, "${test.id} ${test.title}", Toast.LENGTH_SHORT).show()
}
}
it is first data
after update data, items with the same id have not been updated (id 2, 3)

Recyclerview keep being reset

I'm facing a problem with my recycler view, I'd wanted to refresh it every second, for that I use a timer which creates new request, but I think that my recyclerview is destroyed and directly recreated, when I'm scrolling it keep always returning to the top every second. Here is my fragment, I heard about layoutmanager but don't really know how to use it, is it linked?
class DlFragment (private val context: MainActivity): Fragment(){
private var myTimer: Timer? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_dl,container, false)
val dlRecyclerView = view?.findViewById<RecyclerView>(R.id.dl_list_recycle_view)
myTimer = Timer()
myTimer!!.schedule(object : TimerTask() {
override fun run() {
getDlList(dlRecyclerView)
}
}, 0, 1000)
val comfirmButton= view.findViewById<Button>(R.id.input_post_dl_button)
comfirmButton.setOnClickListener { postDl(view) }
return view
}
private fun getDlList(dlRecyclerView: RecyclerView?) {
GlobalScope.launch(Dispatchers.Main) {
try {
val response = ApiClientQnap.apiServiceQnap.getQuery(0,20,"all","all",ApiClientQnap.sid)
if (response.isSuccessful && response.body() != null) {
val content = response.body()
if (content != null) {
//println(content)
//val dlRecyclerView = view?.findViewById<RecyclerView>(R.id.dl_list_recycle_view)
dlRecyclerView?.adapter = DlAdapter(context,content.data)
}
} else { println("Error Occurred: ${response.message()}") }
} catch (e: Exception) {println("Error Occurred: ${e.message}") }
}
}
private fun postDl(view: View){
val url_Dl = view.findViewById<EditText>(R.id.input_post_dl_text)
GlobalScope.launch(Dispatchers.Main) {
try {
val response = ApiClientQnap.apiServiceQnap.postDL("Films","Films",
url_Dl.text.toString(),ApiClientQnap.sid)
if (response.isSuccessful && response.body() != null) {
val content = response.body()
println(response.body())
if (content != null) {
if(content.error == 0) {
Toast.makeText(context, "yeee", Toast.LENGTH_LONG).show()
url_Dl.text.clear()
}
else
Toast.makeText(context, "no", Toast.LENGTH_LONG).show()
}
} else { println("Error Occurred: ${response.message()}") }
} catch (e: Exception) {println("Error Occurred: ${e.message}") }
}
}
Edit: Here's my DlAdapter
class DlAdapter(
val context: MainActivity,
private var dlList: ArrayList<Data>
) : RecyclerView.Adapter<DlAdapter.ViewHolder>() {
class ViewHolder(view : View): RecyclerView.ViewHolder(view){
val dl_title = view.findViewById<TextView>(R.id.dl_title)
val dl_progress = view.findViewById<TextView>(R.id.dl_progress)
val dl_speed = view.findViewById<TextView>(R.id.dl_speed)
val progressBar = view.findViewById<ProgressBar>(R.id.progressBar)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.fragment_dl_list,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val currentDl = dlList[position]
holder.dl_title.text = currentDl.source_name
holder.progressBar.progress = (currentDl.progress!!)
when (currentDl.state) {
5 -> holder.dl_progress.text = ("Terminé")
2 -> holder.dl_progress.text = ("Arrété")
4 -> holder.dl_progress.text = ("Echec")
1 -> holder.dl_progress.text = (currentDl.progress.toString() + " % En pause")
104 -> {
holder.dl_progress.text = (currentDl.progress.toString() + " %")
var toFloat = currentDl.down_rate?.toFloat()
toFloat = toFloat?.div(1000000)
holder.dl_speed.text = (toFloat.toString()+" Mo")
}
}
}
override fun getItemCount(): Int = dlList.size
fun updateData(newData: ArrayList<Data>) {
dlList.clear()
dlList.addAll(newData)
notifyDataSetChanged()
}
}
As #hardartcore suggested, you can try to convert the RecyclerView.Adapter to a ListAdapter and use a DiffUtil.ItemCallback class.
Try to convert your adapter like this:
class DlAdapter : ListAdapter<Data, DlAdapter.ViewHolder>(DlDiffCallback()) {
class ViewHolder(view : View): RecyclerView.ViewHolder(view){
val dl_title = view.findViewById<TextView>(R.id.dl_title)
val dl_progress = view.findViewById<TextView>(R.id.dl_progress)
val dl_speed = view.findViewById<TextView>(R.id.dl_speed)
val progressBar = view.findViewById<ProgressBar>(R.id.progressBar)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.fragment_dl_list,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// Use the getItem method to retrieve a specific item
val currentDl = getItem(position)
holder.dl_title.text = currentDl.source_name
holder.progressBar.progress = (currentDl.progress!!)
when (currentDl.state) {
5 -> holder.dl_progress.text = ("Terminé")
2 -> holder.dl_progress.text = ("Arrété")
4 -> holder.dl_progress.text = ("Echec")
1 -> holder.dl_progress.text = (currentDl.progress.toString() + " % En pause")
104 -> {
holder.dl_progress.text = (currentDl.progress.toString() + " %")
var toFloat = currentDl.down_rate?.toFloat()
toFloat = toFloat?.div(1000000)
holder.dl_speed.text = (toFloat.toString()+" Mo")
}
}
}
}
class DlDiffCallback : DiffUtil.ItemCallback<Data>() {
// Change this method comparisons based on your equality conditions
override fun areItemsTheSame(oldItem: DataItem, newItem: DataItem): Boolean = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: DataItem, newItem: DataItem): Boolean = oldItem == newItem
}
You can then update your RecyclerView adapter by using the submitList method:
val adapter = DlAdapter()
adapter.submitList(content.data)

DiffUtil areContentsTheSame() always returns true, after the contents are updated of the List in RecycleViewAdapter

This is my RecyclerView Adapter Class. Clicking an item from the list UI should change of the particular item like background black to white. After clicking an item I am changing the status of the item 0 to 1 from the UI class, based on that status UI should change of the item. But inside diffUtil areContentTheSame() retures true.
class TimeSlotsAdapter(val adapterItemOnClick: (TimeSlots) -> Unit):RecyclerView.Adapter<TimeSlotsAdapter.TimeSlotsViewHolder>() {
private lateinit var binding: RvTimeSlotsBinding
private var timeSlots: List<TimeSlots> = ArrayList<TimeSlots>()
inner class TimeSlotsViewHolder : RecyclerView.ViewHolder {
constructor(rvBinding: RvTimeSlotsBinding) : super(rvBinding.root) {
}
fun setItem(timeSlots: TimeSlots) {
binding.timeSlotView.setOnClickListener { adapterItemOnClick(timeSlots) }
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TimeSlotsViewHolder {
binding =
RvTimeSlotsBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return TimeSlotsViewHolder(binding)
}
override fun onBindViewHolder(holder: TimeSlotsViewHolder, position: Int) {
timeSlots[position]?.let { currentSlot ->
with(holder) {
if (currentSlot.status == "1") {
binding.timeSlotView.background =
ContextCompat.getDrawable(
binding.timeSlotView.context,
R.drawable.time_slot_item_bg
)
binding.timeSlotTv.setTextColor(
ContextCompat
.getColor(binding.timeSlotTv.context, R.color.black)
)
binding.timeSlotTv.text = "1 " + currentSlot.time
Timber.e("${currentSlot.time} ${currentSlot.status}")
} else {
binding.timeSlotView.background =
ContextCompat.getDrawable(
binding.timeSlotView.context,
R.drawable.black_bg
)
binding.timeSlotTv.setTextColor(
ContextCompat
.getColor(binding.timeSlotTv.context, R.color.white)
)
binding.timeSlotTv.text = "0 " + currentSlot.time
Timber.e("${currentSlot.time} ${currentSlot.status}")
}
setItem(currentSlot)
}
}
}
override fun getItemCount(): Int = timeSlots.size
fun submitSlots(timeSlotList: List<TimeSlots>) {
val oldList = timeSlots
val diffResult: DiffUtil.DiffResult = DiffUtil.calculateDiff(
TimeSlotsDiffCallBack(
oldList,
timeSlotList
)
)
timeSlots = timeSlotList
diffResult.dispatchUpdatesTo(this)
}
class TimeSlotsDiffCallBack(
var oldTimeSlotsList: List<TimeSlots>,
var newTimeSlotsList: List<TimeSlots>
) : DiffUtil.Callback() {
override fun getOldListSize(): Int = oldTimeSlotsList.size
override fun getNewListSize(): Int = newTimeSlotsList.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return (oldTimeSlotsList[oldItemPosition].time
== newTimeSlotsList[newItemPosition].time)
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldTimeSlots = oldTimeSlotsList[oldItemPosition].status
val newTimeSlots = newTimeSlotsList[newItemPosition].status
Timber.e("old: $oldTimeSlots new: $newTimeSlots")
return oldTimeSlots == newTimeSlots
}
}
}
This is the UI class for submitting adapter list. Below the doClickTimeSlot() I am updating the status of the items.
class TimeSlotBottomSheetFragment : BottomSheetDialogFragment(){
private val obj: List<TimeSlots> = mutableListOf<TimeSlots>(
TimeSlots("09:30", "0"),
TimeSlots("10:30", "0"),
TimeSlots("11:30", "0"),
TimeSlots("12:30", "0"),
TimeSlots("14:30", "0"),
TimeSlots("15:30", "0"),
TimeSlots("16:30", "0"),
TimeSlots("17:30", "0"),
TimeSlots("18:30", "0"),
TimeSlots("19:30", "0"),
TimeSlots("20:30", "0"),
TimeSlots("21:30", "0")
)
private fun doClickTimeSlot(timeSlots: TimeSlots) {
val newList: ArrayList<TimeSlots> = ArrayList<TimeSlots>()
newList.addAll(obj)
for (i in newList.indices) {
if (newList[i].time == timeSlots.time) {
newList[i].status = "1"
Timber.e("" + newList[i].time + " " + newList[i].status)
} else {
newList[i].status = "0"
Timber.e("" + newList[i].time + " " + newList[i].status)
}
}
adapter.submitSlots(newList)
}
}

how to insert items by title and subitem, using getItemViewType

How to insert an arraylist in recyclingeview by sorting before inserting. Just below the example
[PRATO FEITO ] -> TITLE
[ COM ACOMPANHAMENTO] -> SUB ITEM
[ COM FEIJOADA ] -> SUB ITEM
[ ]
[ESPETINHO ] -> TITLE
[ COM BIFÉ ] -> SUB ITEM
[ COM ACOMPANHAMENTO] -> SUB ITEM
See how the result is doing. It's running out of order
[PRATO FEITO ] -> TITLE
[ESPETINHO ] -> TITLE
[ COM BIFÉ ] -> SUB ITEM
[ COM ACOMPANHAMENTO] -> SUB ITEM
[ COM FEIJOADA ] -> SUB ITEM
[ COM MANDIOCA ] -> SUB ITE
My Code List
class Lista_Itens_Mesa : AppCompatActivity() {
val client by lazy {
Api.create()
}
var disposable: Disposable? = null
private lateinit var recycleview: RecyclerView
private lateinit var viewadapter1: RecyclerView.Adapter<*>
private lateinit var viewManager: RecyclerView.LayoutManager
private lateinit var db: AppBancoDados
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.lista__itens__mesa_pratos) //lista__itens__mesa_pratos
val numbercolumns = 1
recyclerViewItens_Mesa.layoutManager = LinearLayoutManager(this)
recyclerViewItens_Mesa.addItemDecoration(DividerItemDecoration(this, OrientationHelper.HORIZONTAL))
BuscarTestando()
}
fun BuscarTestando(){
disposable = client.list_pratos(idmesas)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ result ->
val array = ArrayList<Pr_atos>()
result[0].pratos.forEach {
array.add(Pr_atos(it?.dESCRICAOPRODUTO, null, it?.POST_TYPE))
}
result[1].complementos.forEach {
array.add(Pr_atos(null, it?.cOMPLEMENTODESCRICAO, it?.POST_TYPE))
}
viewadapter1 = Itens_Mesa_Adapter(array)
recyclerViewItens_Mesa.adapter = viewadapter1
},
{ error ->
println(" Erro não esperado! " + error.printStackTrace())
})
}
}
My Adapter Custom
private const val POST_TYPE_PRATOS : Int = 1
private const val POST_TYPE_COMPLEMENTOS: Int = 0
class Itens_Mesa_Adapter( var itens_mesa:List<Pr_atos>): RecyclerView.Adapter<RecyclerView.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if(viewType == POST_TYPE_PRATOS){
val view_pratos = LayoutInflater.from(parent.context).inflate(R.layout.itens__mesa_pratos,parent,false)
return ViewHolderPratos(view_pratos)
}else(viewType == POST_TYPE_COMPLEMENTOS)
val view_complementos = LayoutInflater.from(parent.context).inflate(R.layout.itens_mesa_complemento,parent,false)
return ViewHolderComplementos(view_complementos)
}
override fun getItemCount(): Int {
return itens_mesa.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(getItemViewType(position) == POST_TYPE_PRATOS){
(holder as ViewHolderPratos).bind(itens_mesa[position])
}else{
(holder as ViewHolderComplementos).bind(itens_mesa[position])
}
}
override fun getItemViewType(position: Int): Int {
return if(itens_mesa[position].post_type == 1){
POST_TYPE_PRATOS
}else{
POST_TYPE_COMPLEMENTOS
}
}
class ViewHolderPratos(itemView: View) : RecyclerView.ViewHolder(itemView){
fun bind(itens : Pr_atos){
itemView.TextViewPedidoName.text = itens.produtoname
}
}
class ViewHolderComplementos(itemView: View) : RecyclerView.ViewHolder(itemView){
fun bind(itens: Pr_atos){
itemView.textViewcomplemento_pedido.text = itens.complementoname
}
}
}

Kotlin: Show AlertDialog when RecycleView item clicked

Now I'm studying to show AlertDialog when RecyclerView item clicked.
However, I don't know how to set the adapter for click listener.
Could you give me a tip?
Firstly, I tried to put the AlertDialog in this Main Activity.
Is this right position?
MainActivity
class MainActivity : AppCompatActivity() {
private val foodList = listOf(
FoodModel("Noodle", 2),
FoodModel("Cake", 3),
FoodModel("Pizza", 4),
FoodModel("Stake", 5),
FoodModel("Chicken", 4)
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adapter = FoodDataAdapter(foodList)
adapter.notifyDataSetChanged()
foodListView.adapter = adapter
foodListView.layoutManager = LinearLayoutManager(this)
fun onItemClick(item: FoodModel, position: Int) {
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Item deletion")
dialog.setMessage("Do you want to delete this item?")
dialog.setPositiveButton("Yes", DialogInterface.OnClickListener { _, _ ->
})
dialog.setNegativeButton("No", DialogInterface.OnClickListener { _, _ ->
})
dialog.setNeutralButton("Cancel", DialogInterface.OnClickListener { _, _ ->
})
dialog.show()
}
}
}
This is the Adapter.
class FoodDataAdapter(val list: List<FoodModel>):RecyclerView.Adapter<FoodDataViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FoodDataViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_food,parent,false)
return FoodDataViewHolder(view)
}
override fun getItemCount(): Int {
return list.count()
}
override fun onBindViewHolder(holder: FoodDataViewHolder, position: Int) {
holder.containerView.nameText.text=list[position].name
holder.containerView.priceText.text="${list[position].price}dollar"
}
}
View holder
class FoodDataViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView),LayoutContainer
I edited your code. MainActivity:
class MainActivity : AppCompatActivity(), FoodDataAdapter.OnItemClickListener {
var foodList = ArrayList<FoodModel>()
lateinit var adapter : FoodDataAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
foodlist.add(FoodModel("Noodle", 2))
foodlist.add(FoodModel("Cake", 3))
foodlist.add(FoodModel("Pizza", 4))
foodlist.add(FoodModel("Stake", 5))
foodlist.add(FoodModel("Chicken", 4))
adapter = FoodDataAdapter(foodList, this)
foodListView.adapter = adapter
foodListView.layoutManager = LinearLayoutManager(this)
}
override fun alertDialog(position: Int) {
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Item deletion")
dialog.setMessage("Do you want to delete this item?")
dialog.setPositiveButton("Yes", DialogInterface.OnClickListener { _, _ ->
adapter.removeItem(position)
})
dialog.setNegativeButton("No", DialogInterface.OnClickListener { _, _ ->
})
dialog.setNeutralButton("Cancel", DialogInterface.OnClickListener { _, _ ->
})
dialog.show()
}
}
FoodDataAdapter:
class FoodDataAdapter(var list: ArrayList<FoodModel>, var listener : FoodDataAdapter.OnItemClickListener):RecyclerView.Adapter<FoodDataAdapter.FoodDataViewHolder>(){
interface OnItemClickListener {
fun alertDialog(position : Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FoodDataViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_food,parent,false)
return FoodDataViewHolder(view)
}
override fun getItemCount(): Int {
return list.count()
}
fun removeItem(position: Int) {
list.removeAt(position)
notifyItemRemoved(position)
}
override fun onBindViewHolder(holder: FoodDataViewHolder, position: Int) {
holder.nameText.text=list[position].name
holder.priceText.text="${list[position].price}dollar"
}
inner class FoodDataViewHolder(containerView: View) : RecyclerView.ViewHolder(containerView),
View.OnClickListener {
var nameText: TextView = containerView.findViewById(R.id.nameText)
var priceText: TextView = containerView.findViewById(R.id.priceText)
init {
containerView.setOnClickListener(this)
}
override fun onClick(v: View?) {
listener.alertDialog(adapterPosition)
}
}
}
I just put a declare code for 'removeAt' at the end of the Adapter like this,
class FoodDataAdapter(val list: List<FoodModel>,var itemClicklistener : OnItemClickListener):RecyclerView.Adapter<FoodDataAdapter.FoodDataViewHolder>() {
interface OnItemClickListener {
fun onItemClick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FoodDataViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_food, parent, false)
return FoodDataViewHolder(view)
}
override fun getItemCount(): Int {
return list.count()
}
fun removeItem(position: Int) {
list.removeAt(position)
notifyItemRemoved(position)
}
override fun onBindViewHolder(holder: FoodDataViewHolder, position: Int) {
holder.nameText.text = list[position].name
holder.priceText.text = "${list[position].price} dollar"
}
inner class FoodDataViewHolder(containerView: View) : RecyclerView.ViewHolder(containerView),
View.OnClickListener {
var nameText: TextView = containerView.findViewById(R.id.nameText)
var priceText: TextView = containerView.findViewById(R.id.priceText)
init {
containerView.setOnClickListener(this)
}
override fun onClick(v: View?) {
itemClicklistener.onItemClick(adapterPosition)
}
}
}
private fun Any.removeAt(position: Int) {
}
and also changed the Main activity like this.
class MainActivity : AppCompatActivity(), FoodDataAdapter.OnItemClickListener {
private val foodList = arrayListOf(
FoodModel("Noodle", 3),
FoodModel("Cake", 5),
FoodModel("Pizza", 7),
FoodModel("Stake", 8),
FoodModel("Chicken", 8)
)
var adapter: FoodDataAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
adapter = FoodDataAdapter(foodList, this)
foodListView.adapter = adapter
foodListView.layoutManager = LinearLayoutManager(this)
}
override fun onItemClick(position: Int) {
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Item deletion")
dialog.setMessage("Do you want to delete this item?")
dialog.setPositiveButton("Yes", DialogInterface.OnClickListener { _, _ ->
adapter?.removeItem(position)
})
dialog.setNegativeButton("No", DialogInterface.OnClickListener { _, _ ->
})
dialog.setNeutralButton("Cancel", DialogInterface.OnClickListener { _, _ ->
})
dialog.show()
}
}
And it works! but...one problem is..
after deletion of the list, the last list keep comes up.
the total number of list was not decreased..
lol
another 'Chicken' comes up..do you know how to fix it?