Android RecyclerView Buttons Under Swipe (HalfSwipe)

 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 
  1.   Context 
  2.   View [RecyclerView]
  3.   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  
  1.   label 
  2.   icon 
  3.   Backgroundcolor
  4.   textColor
  5.   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
    }

}



RecyclerView Related
  1. RecyclerView
  2. RecyclerView Item Click Ripple Effect
  3. RecyclerView With Item Divider
  4. RecyclerView With CardView
  5. RecyclerView GridLayout
  6. RecyclerView StaggeredGrid Layout
  7. RecyclerView Swipe To Delete

3 comments:

Anonymous said...

Hi bro, How to add ripple effect when user click on "Archive" ?

Unknown said...

Sir please show how to center align button without text.

Unknown said...

your code is very helpful for me thank you so much

Post a Comment