Sean Kim
Sean Kim

Reputation: 35

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

Upvotes: 0

Views: 1339

Answers (2)

Sean Kim
Sean Kim

Reputation: 35

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..

enter image description here enter image description here

lol another 'Chicken' comes up..do you know how to fix it?

Upvotes: 0

Kasım &#214;zdemir
Kasım &#214;zdemir

Reputation: 5644

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

Upvotes: 2

Related Questions