RecyclerView is a ViewGroup ,that display a scrolling list of elements based on large data sets (or data that frequently changes). RecyclerView widget is more flexible and efficient version of ListView .
In the previous series of tutorials we have seen Recyclerview with itemTouchHelper for swipe(fullscreen)
In this tutorial we will see half swipe for items of reyclerview with buttons under it and performing action on click of it .
Add RecyclerView To XML Layout
Create XML Layout activity_main.xml , this will be set as content view for launcher Activity (MainActivity.kt) and add RecyclerView to your layout file .
file : activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/recyclerView"/>
Data Class
file : Model.kt
package com.tutorialsbuzz.recyclerviewswipebuttons data class Model(val name: String, val version:String) {}
To Load Data Into RecyclerView , We will read JSON File Kept Inside Asset folder and map it to above defined data class
file : main\assets\android_version.json
[ { "name": "Cupcake", "version": "Android 1.5" }, { "name": "Donut", "version": "Android 1.6" }, { "name": "Eclairs", "version": "Android 2.0-2.1" }, { "name": "Froyo", "version": "Android 2.2-2.3" }, { "name": "Gingerbread", "version": "Android 2.3-2.3.7" }, { "name": "Honeycomb", "version": "Android 3.0-3.2.6" }, { "name": "Icecream", "version": "Android 4.0-4.0.4" }, { "name": "Jellybean", "version": "Android 4.1-4.3.1" }, { "name": "Kitkat", "version": "Android 4.4-4.4.4" }, { "name": "Lolipop", "version": "Android 5.0-5.1.1" }, { "name": "Marshmallow", "version": "Android 6.0-6.0.1" }, { "name": "Nougat", "version": "Android 7.0-7.1.2" }, { "name": "Oreo", "version": "Android 8.0-8.1" }, { "name": "Pie", "version": "Android 9.0" } ]
Adapter and ViewHolder For RecyclerView
1. XML Layout For RecyclerView Item
Create XML Layout file in res/layout and name it row_item.xml .This Layout defines the layout for
Items of RecyclerView . Here In this example we have two TextView inside LinearLayout .
file : row_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:orientation="vertical"> <ImageView android:layout_width="80dp" android:layout_height="80dp" android:id="@+id/img" android:contentDescription="@string/app_name"/> <TextView android:id="@+id/txt" android:textSize="22sp" android:text="Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:layout_toEndOf="@+id/img" android:layout_marginStart="20dp"/> <TextView android:id="@+id/sub_txt" android:textSize="18sp" android:text="Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="italic" android:layout_toEndOf="@+id/img" android:layout_below="@+id/txt" android:layout_marginStart="20dp"/> </RelativeLayout>
2. Adapter and ViewHolder
- Create a Adapter That RecyclerView Can Use , Create a class CustomAdapter extend it to RecyclerView.Adapter .
- Create Inner class ViewHolder extend it to RecyclerView.ViewHolder
ItemTouchHelper For RecyclerView [Swipe With Button]
To Achieve half swipe with buttons under Inside onChildDraw() function of ItemTouchHelper.SimpleCallback using canvas we will draw button The complete code for SwipeHelper , we will attach recyclerview to it and create buttons for items of recyclerview on swipe .
Create an instance of SwipeHelper and pass recyclerView .
It Takes following paramater
- Context
- View [RecyclerView]
- Boolean [for animation ]
Override instantiateUnderlayButton of SwipeHelper class , using underlayButtons paramater of instantiateUnderlayButton fun add buttons (i.e add instance of UnderlayButton )
Each Buttons is an instance of UnderlayButton and it takes following paramaters
- label
- icon
- Backgroundcolor
- textColor
- clickListener
object : SwipeHelper(this, recyclerView, false) { override fun instantiateUnderlayButton( viewHolder: RecyclerView.ViewHolder?, underlayButtons: MutableList<UnderlayButton>? ) { // Archive Button underlayButtons?.add(SwipeHelper.UnderlayButton( "Archive", AppCompatResources.getDrawable( this@MainActivity, R.drawable.ic_archive_black_24dp ), Color.parseColor("#000000"), Color.parseColor("#ffffff"), UnderlayButtonClickListener { pos: Int -> Toast.makeText( this@MainActivity, "Delete clicked at " + pos, Toast.LENGTH_SHORT ).show() adapter.modelList.removeAt(pos); adapter.notifyItemRemoved(pos) } )) // Flag Button underlayButtons?.add(SwipeHelper.UnderlayButton( "Flag", AppCompatResources.getDrawable( this@MainActivity, R.drawable.ic_flag_black_24dp ), Color.parseColor("#FF0000"), Color.parseColor("#ffffff"), UnderlayButtonClickListener { pos: Int -> Toast.makeText( this@MainActivity, "Flag Button Clicked at Position: " + pos, Toast.LENGTH_SHORT ).show() adapter.notifyItemChanged(pos) } )) // More Button underlayButtons?.add(SwipeHelper.UnderlayButton( "More", AppCompatResources.getDrawable( this@MainActivity, R.drawable.ic_more_horiz_black_24dp ), Color.parseColor("#00FF00"), Color.parseColor("#ffffff"), UnderlayButtonClickListener { pos: Int -> Toast.makeText( this@MainActivity, "More Button CLicked at Position: " + pos, Toast.LENGTH_SHORT ).show() adapter.notifyItemChanged(pos) } )) } }
MainActivity
Complete MainActivity
file : MainActivity.kt
package com.tutorialsbuzz.recyclerviewswipebuttons import android.graphics.Color import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.tutorialsbuzz.recyclerviewswipebuttons.SwipeHelper.UnderlayButtonClickListener import kotlinx.android.synthetic.main.activity_main.* import org.json.JSONArray import org.json.JSONObject class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val modelList = readFromAsset(); val adapter = CustomAdapter(modelList, this) recyclerView.addItemDecoration(SimpleDividerItemDecoration(this)) recyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false) recyclerView.adapter = adapter; object : SwipeHelper(this, recyclerView, false) { override fun instantiateUnderlayButton( viewHolder: RecyclerView.ViewHolder?, underlayButtons: MutableList<UnderlayButton>? ) { // Archive Button underlayButtons?.add(SwipeHelper.UnderlayButton( "Archive", AppCompatResources.getDrawable( this@MainActivity, R.drawable.ic_archive_black_24dp ), Color.parseColor("#000000"), Color.parseColor("#ffffff"), UnderlayButtonClickListener { pos: Int -> Toast.makeText( this@MainActivity, "Delete clicked at " + pos, Toast.LENGTH_SHORT ).show() adapter.modelList.removeAt(pos); adapter.notifyItemRemoved(pos) } )) // Flag Button underlayButtons?.add(SwipeHelper.UnderlayButton( "Flag", AppCompatResources.getDrawable( this@MainActivity, R.drawable.ic_flag_black_24dp ), Color.parseColor("#FF0000"), Color.parseColor("#ffffff"), UnderlayButtonClickListener { pos: Int -> Toast.makeText( this@MainActivity, "Flag Button Clicked at Position: " + pos, Toast.LENGTH_SHORT ).show() adapter.notifyItemChanged(pos) } )) // More Button underlayButtons?.add(SwipeHelper.UnderlayButton( "More", AppCompatResources.getDrawable( this@MainActivity, R.drawable.ic_more_horiz_black_24dp ), Color.parseColor("#00FF00"), Color.parseColor("#ffffff"), UnderlayButtonClickListener { pos: Int -> Toast.makeText( this@MainActivity, "More Button CLicked at Position: " + pos, Toast.LENGTH_SHORT ).show() adapter.notifyItemChanged(pos) } )) } } } private fun readFromAsset(): MutableList<Model> { val modeList = mutableListOf<Model>() val bufferReader = application.assets.open("android_version.json").bufferedReader() val json_string = bufferReader.use { it.readText() } val jsonArray = JSONArray(json_string); for (i in 0..jsonArray.length() - 1) { val jsonObject: JSONObject = jsonArray.getJSONObject(i) val model = Model(jsonObject.getString("name"), jsonObject.getString("version")) modeList.add(model) } return modeList } }
3 comments:
Hi bro, How to add ripple effect when user click on "Archive" ?
Sir please show how to center align button without text.
your code is very helpful for me thank you so much
Post a Comment