How to show a popup Alert in Android with a RecyclerView in Kotlin
How to show a popup Alert in Android(Kotlin) with a RecyclerView:
In this tutorial, I will show you how to create an Alert
in Android with Kotlin. It will show one Alert
once the user clicks on the delete button. We will use the same project used in the previous RecyclerView
examples.
YouTube video:
I published a video on YouTube. You can watch it here:
Please do subscribe to my channel if you love this video.
Project Setup:
We will use one Node.js
backend for this example project. You can download the project from this GitHub link. You need to run npm install && npm run start
or yarn && yarn start
to start the server on the 3000
port.
localhost:3000
will return the response array used in this example.
Changes in the ApiService class:
For this example, we will use a vertical RecyclerView
. Change the ApiService.kt
file to fetch the data without horizontal RecyclerView
data:
import com.example.myapplication.models.Propertyimport com.squareup.moshi.Moshiimport com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactoryimport retrofit2.Callimport retrofit2.Retrofitimport retrofit2.converter.moshi.MoshiConverterFactoryimport retrofit2.http.GETprivate const val BASE_URL = "http://10.0.2.2:3000"private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()private val retrofit = Retrofit.Builder().addConverterFactory(MoshiConverterFactory.create(moshi)).baseUrl(BASE_URL).build()interface ApiService{+ @GET(".")fun getAllData(): Call<List<Property>>}object Api {val retrofitService: ApiService by lazy{retrofit.create(ApiService::class.java)}}
Changes in the adapter:
On clicking the delete button, the adapter class will call a method in the MainActivity
class. The alert will be shown in the MainActivity
class file.
We need to update the MyAdapter.kt
file as below:
import android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport android.widget.Buttonimport android.widget.ImageViewimport android.widget.TextViewimport androidx.constraintlayout.widget.ConstraintLayoutimport androidx.recyclerview.widget.LinearLayoutManagerimport androidx.recyclerview.widget.RecyclerViewimport com.bumptech.glide.Glideimport com.example.myapplication.models.Propertyimport org.w3c.dom.Text+ class MyAdapter(private val data: List<Property>, val onClickDelete: (Int) -> Unit) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {private var listData: MutableList<Property> = data as MutableList<Property>inner class MyViewHolder(val view: View): RecyclerView.ViewHolder(view){fun bind(property: Property, index: Int){val title = view.findViewById<TextView>(R.id.tvTitle)val imageView = view.findViewById<ImageView>(R.id.imageView)val description = view.findViewById<TextView>(R.id.tvDescription)val button = view.findViewById<Button>(R.id.button)val constraintLayout = view.findViewById<ConstraintLayout>(R.id.constraintLayout)val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView)constraintLayout.visibility = View.VISIBLErecyclerView.visibility = View.GONEtitle.text = property.titledescription.text = property.descriptionGlide.with(view.context).load(property.image).centerCrop().into(imageView)button.setOnClickListener{deleteItem(index)}}fun bindRecyclerView(data: List<Property>){val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView)val constraintLayout = view.findViewById<ConstraintLayout>(R.id.constraintLayout)constraintLayout.visibility = View.GONErecyclerView.visibility = View.VISIBLEval manager : RecyclerView.LayoutManager = LinearLayoutManager(view.context, LinearLayoutManager.HORIZONTAL, true)recyclerView.apply{val data = data as MutableList<Property>var myAdapter = MyAdapter(data){index -> deleteItem(index)}layoutManager = manageradapter = myAdapter}}}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)return MyViewHolder(v)}override fun getItemCount(): Int {return listData.size}override fun onBindViewHolder(holder: MyViewHolder, position: Int) {if(listData[position].horizontal){listData[position].data?.let { holder.bindRecyclerView(it)}}else {holder.bind(listData[position], position)}}fun deleteItem(index: Int){+ onClickDelete(index)}+ fun setItems(items: List<Property>){+ listData = items as MutableList<Property>+ notifyDataSetChanged()+ }}
- The
onClickDelete
is a callback method. This method will be called once the user will click on the delete button. - In the
MainActivity
, we will show oneAlert
inonClickDelete
. - If the user clicks on the
Delete
button of theAlert
, we will remove that item from the list and update the list in the adapter with thesetItems
method.
MainActivity.kt file change:
The MainActivity
file is changed as below:
import androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.os.Handlerimport android.os.Looperimport android.view.Viewimport android.widget.Toastimport androidx.appcompat.app.AlertDialogimport androidx.recyclerview.widget.LinearLayoutManagerimport androidx.recyclerview.widget.RecyclerViewimport androidx.swiperefreshlayout.widget.SwipeRefreshLayoutimport com.example.myapplication.models.Propertyimport com.example.myapplication.network.Apiimport com.facebook.shimmer.ShimmerFrameLayoutimport retrofit2.Callimport retrofit2.Callbackimport retrofit2.Responseclass MainActivity : AppCompatActivity() {lateinit var data: MutableList<Property>private lateinit var recyclerView: RecyclerViewprivate lateinit var manager: RecyclerView.LayoutManagerprivate lateinit var myAdapter: MyAdapterprivate lateinit var swipeRefresh: SwipeRefreshLayoutprivate lateinit var shrimmerView: ShimmerFrameLayoutoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)manager = LinearLayoutManager(this)swipeRefresh = findViewById(R.id.swipeRefresh)shrimmerView = findViewById(R.id.shimmer_view_container)swipeRefresh.setOnRefreshListener {getAllData()}getAllData()}fun getAllData(){Api.retrofitService.getAllData().enqueue(object: Callback<List<Property>>{override fun onResponse(call: Call<List<Property>>,response: Response<List<Property>>) {shrimmerView.stopShimmer()shrimmerView.visibility = View.GONEif(swipeRefresh.isRefreshing){swipeRefresh.isRefreshing = false}if(response.isSuccessful){recyclerView = findViewById<RecyclerView>(R.id.recycler_view).apply{data = response.body() as MutableList<Property>+ myAdapter = MyAdapter(data){index -> deleteItem(index)}layoutManager = manageradapter = myAdapter}}}override fun onFailure(call: Call<List<Property>>, t: Throwable) {t.printStackTrace()}})}+ fun deleteItem(index: Int){+ val alertBuilder = AlertDialog.Builder(this)+ alertBuilder.setTitle("Delete")+ alertBuilder.setMessage("Do you want to delete this item ?")+ alertBuilder.setPositiveButton("Delete"){_,_ ->+ if(::data.isInitialized && ::myAdapter.isInitialized){+ data.removeAt(index)+ myAdapter.setItems(data)+ Toast.makeText(this, "Item deleted", Toast.LENGTH_SHORT).show()+ }+ }++ alertBuilder.setNegativeButton("No"){_,_ ->++ }++ alertBuilder.setNeutralButton("Cancel"){_,_ ->++ }+ alertBuilder.show()+ }+}
- On initializing the adapter, we are passing the callback method
MyAdapter(data){index -> deleteItem(index)}
. - It will call the
deleteItem
method if the user clicks on the delete button. - We are creating one
AlertDialog
by using theAlertDialog.Builder
method. ThesetTitle
andsetMessage
methods are used to set the title and message for the alert. ThesetPositiveButton
,setNegativeButton
andsetNeutralButton
methods are used to add three buttons to the dialog. We can add the code to execute in the callback method. On clicking these buttons, it will execute the code. - The
show
method is used to show theAlertDialog
. - On clicking the delete button, it removes the item at the given index from the data and assigns the new items to the adapter by using the
setItems
method.
Output:
If you run the program, it will show you the list. You can click on the delete button of any item and it will show you one AlertDialog
as shown below:
Download the code:
The code is available on Github. Please use the tut-alert
tag to get the code used in this tutorial.
git clone https://github.com/AppDevAssist/recyclerview-kotlin && git checkout tags/tut-alert