- App’s Overview
- Table Of Content
- Dependencies Setup
- Code Explanation
- GitHub Repository
- Siddharth-sing / Swipe-delete-from-firebase-
- This app will demonstrate the swipe to delete from firebase feature.
- Article is on dev.to click below 👇
- App’s Overview
- Note:
- Table Of Content
- Code Explanation
- Swipeable RecyclerView in Android using Kotlin.
- What is Recycler view?
- Why Swipeable Recycler View over simple one?
- Creating a New Project:
- Adding Dependencies to Gradle:
- How to implement, drag and drop and swipe to delete in recyclerview?
- 4 Answers 4
App’s Overview
The article only contains the explanation of «swipe to delete» feature, firebase implementation and UI details are not discussed, but I will provide the GitHub from which you can easily go through the complete code of the app.
Table Of Content
Dependencies Setup
- I have used an external library to create and decorate the swipe to delete feature, it is called RecyclerViewSwipeDecorator.
Code Explanation
- Create an ItemTouchHelper.SimpleCallback , instantiate an ItemTouchHelper with this callback.
- Copy the code snippet below 👇
/* -> `SimpleCallback` gives us option to tell about the swipe direction. -> `ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT` */ val callback: ItemTouchHelper.SimpleCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT) < override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean < return false >override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) < //Take action for swiped direction //Delete on swipe left //Archive on swipe right //Customise according to your mood >
- Now let us attach our ItemTouchHelper with the RecyclerView .
- Copy the below 👇 code snippet just outside callback
val itemTouchHelper = ItemTouchHelper(callback) itemTouchHelper.attachToRecyclerView(rv) /* rv - replace with your recycler view variable name */
- The above code is sufficient for the swipe to delete feature. It will look something like below 👇
- To decorate our swipe feature we will override onChildDraw method. This method has various functions, some of them will be discussed in this article others you can explore here.
- Override onChildDraw method below onSwiped method.
- Copy the below code snippet👇
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) < RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) .addBackgroundColor( ContextCompat.getColor( this@ListActivity, android.R.color.holo_red_light ) ) .addActionIcon(R.drawable.ic_baseline_delete_sweep_24) // add any icon of your choice .addSwipeRightLabel("Deleting the Item") //Label according to your choice .addSwipeLeftLabel("Deleting the Item") .setSwipeRightLabelColor(R.color.white) // behind color on swiping .setSwipeLeftLabelColor(R.color.white) .create() .decorate() super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) >
GitHub Repository
Siddharth-sing / Swipe-delete-from-firebase-
This app will demonstrate the swipe to delete from firebase feature.
Article is on dev.to click below 👇
App’s Overview
- In this article I am gonna take you through the development of Swipe Delete Feature, specifically we are going to delete the data present in Cloud Firestore Database in just a swipe.
- Sounds amazing, yes it is amazing, let’s start :
Note:
The article only contains the explanation of «swipe to delete» feature, firebase implementation and UI details are not discussed, but I will provide the GitHub from which you can easily go through the complete code of the app.
Table Of Content
- I have used an external library to create and decorate the swipe to delete feature, it is called RecyclerViewSwipeDecorator.
Code Explanation
- Create an ItemTouchHelper.SimpleCallback , instantiate an ItemTouchHelper with this callback.
- Copy the code snippet below 👇
Swipeable RecyclerView in Android using Kotlin.
Let’s, first of all, see what is swipeable. Swipeable in terms of swiping items or elements both right and left side, to perform specific operations on it as shown in the sample output below. Before starting, let’s see what is Recycler View and when it should be used.
What is Recycler view?
Many apps need to display UI elements based on large data sets, or data that frequently changes. For example, a music app might need to display information about thousands of albums, but only a dozen of those albums might be on-screen at a time or an app like Gmail, which has lots of emails with different categories like sent and received etc. If the app created UI widgets for each of those albums or E-mails, the app would end up using a lot of memory and storage, potentially making the app slow and crash-prone. On the other hand, if the app created UI widgets each time a new album scrolled onto the screen and destroyed the widgets when it scrolled off, that would also cause the app to run slowly, since creating UI objects is a resource-intensive operation.
For this type of situations, we can use Recycler view, instead of List views to handle a large amount of data.
Why Swipeable Recycler View over simple one?
With swipeable recycler view, it would be easy to provide specific functionalities like edit an element or delete an element permanently etc.
Seems Interesting right? So let’s get started!
Creating a New Project:
Open your Android Studio & create a new Project. For Kotlin support, check the checkbox of Kotlin support. Now give name whatever you like and We’ll keep all the things by default and clicked finish.
Adding Dependencies to Gradle:
To create recycler view, add following dependencies.
compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.android.support:design:25.3.1'
We don’t need any permissions from the user for Recycler view.
If your Android studio is not updated (lower version than 3.0), then you have to manually configure Kotlin. So add following line to your dependencies of a project (NOT module as above).
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
So the whole file will look like:
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript < ext.kotlin_version = '1.1.2-4' repositories < jcenter() >dependencies < classpath 'com.android.tools.build:gradle:2.3.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files >> allprojects < repositories < jcenter() >> task clean(type: Delete)
Now rebuild your project. Thus you’ve configured Kotlin manually! Now let’s go ahead.
Now add following `Kotlin` code in your main activity.
MainActivity.kt
package com.example.admin.swipablerecyclerview import android.content.DialogInterface import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.RectF import android.support.design.widget.FloatingActionButton import android.support.v7.app.AlertDialog import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.support.v7.widget.helper.ItemTouchHelper import android.view.View import android.view.ViewGroup import android.widget.EditText import java.util.ArrayList class MainActivity : AppCompatActivity(), View.OnClickListener < private val names = ArrayList() private var adapter: DataAdapter? = null private var recyclerView: RecyclerView? = null private var alertDialog: AlertDialog.Builder? = null private var et_name: EditText? = null private var edit_position: Int = 0 private var view: View? = null private var add = false private val p = Paint() override fun onCreate(savedInstanceState: Bundle?) < super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initViews() initDialog() >private fun initViews() < val fab = findViewById(R.id.fab) as FloatingActionButton fab.setOnClickListener(this) recyclerView = findViewById(R.id.card_recycler_view) as RecyclerView recyclerView. setHasFixedSize(true) val layoutManager = LinearLayoutManager(applicationContext) recyclerView. layoutManager = layoutManager adapter = DataAdapter(names) recyclerView. adapter = adapter names.add("Kaushal") names.add("Alex") names.add("Ram") names.add("Abhishek") names.add("Narendra Modi") adapter. notifyDataSetChanged() initSwipe() >private fun initSwipe() < val simpleItemTouchCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) < override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean < return false >override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) < val position = viewHolder.adapterPosition if (direction == ItemTouchHelper.LEFT) < adapter. removeItem(position) >else < removeView() edit_position = position alertDialog. setTitle("Edit Name") et_name. setText(names[position]) alertDialog. show() >> override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) < val icon: Bitmap if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) < val itemView = viewHolder.itemView val height = itemView.bottom.toFloat() - itemView.top.toFloat() val width = height / 3 if (dX >0) < p.color = Color.parseColor("#388E3C") val background = RectF(itemView.left.toFloat(), itemView.top.toFloat(), dX, itemView.bottom.toFloat()) c.drawRect(background, p) icon = BitmapFactory.decodeResource(resources, R.drawable.ic_edit_white) val icon_dest = RectF(itemView.left.toFloat() + width, itemView.top.toFloat() + width, itemView.left.toFloat() + 2 * width, itemView.bottom.toFloat() - width) c.drawBitmap(icon, null, icon_dest, p) >else < p.color = Color.parseColor("#D32F2F") val background = RectF(itemView.right.toFloat() + dX, itemView.top.toFloat(), itemView.right.toFloat(), itemView.bottom.toFloat()) c.drawRect(background, p) icon = BitmapFactory.decodeResource(resources, R.drawable.ic_delete_white) val icon_dest = RectF(itemView.right.toFloat() - 2 * width, itemView.top.toFloat() + width, itemView.right.toFloat() - width, itemView.bottom.toFloat() - width) c.drawBitmap(icon, null, icon_dest, p) >> super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) > > val itemTouchHelper = ItemTouchHelper(simpleItemTouchCallback) itemTouchHelper.attachToRecyclerView(recyclerView) > private fun removeView() < if (view. parent != null) < (view. parent as ViewGroup).removeView(view) >> private fun initDialog() < alertDialog = AlertDialog.Builder(this) view = layoutInflater.inflate(R.layout.dialog_layout, null) alertDialog. setView(view) alertDialog. setPositiveButton("Save") < dialog, which ->if (add) < add = false adapter. addItem(et_name. text.toString()) dialog.dismiss() >else < names[edit_position] = et_name. text.toString() adapter. notifyDataSetChanged() dialog.dismiss() >> et_name = view. findViewById(R.id.et_name) as EditText > override fun onClick(v: View) < when (v.id) < R.id.fab -> < removeView() add = true alertDialog. setTitle("Add Name") // et_country.setText(""); alertDialog. show() >> > >
Note the method named, onSwiped() here we are detecting swipe on the recycler view item and according to the direction of the swipe, we’ll decide the action: delete or. edit
And using the method named method, onChildDraw() we can draw the background of the element when it is swiped. We are creating an alert dialog when the user clicks on floating action button, for asking new name to be entered.When the user enters the new name we will notify recycler view to add that new name using method notifyDataSetChanged() .
Here is our DataAdapter class.
DataAdapter.kt
package com.example.admin.swipablerecyclerview /** * Created by ADMIN on 5/26/2017. */ import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import java.util.ArrayList internal class DataAdapter(private val names: ArrayList) : RecyclerView.Adapter() < override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): DataAdapter.ViewHolder < val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.row_layout, viewGroup, false) return ViewHolder(view) >override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) < viewHolder.tv_names.text = names[i] >override fun getItemCount(): Int < return names.size >fun addItem(country: String) < names.add(country) notifyItemInserted(names.size) >fun removeItem(position: Int) < names.removeAt(position) notifyItemRemoved(position) notifyItemRangeChanged(position, names.size) >internal inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) < var tv_names: TextView init < tv_names = view.findViewById(R.id.tv_names) as TextView >> >
Using this we are setting data items to recycler view. Below are the necessary layout files.
row_layout.xml
activity_main.xml
dialog_layout.xml
Now run the app and you will able to see the recycler view with different names. Swipe left to delete and swipe right to edit the swiped item.
How to implement, drag and drop and swipe to delete in recyclerview?
Hi I’m new to Kotlin I have almost 1 month programming in it, I have one recycler I’m trying to re order the cardviews in the recycler and delete the ones that I don’t need by swipping it, how can I achieve this? could it be done with a library? I couldn’t find one this is what I have: Adapter
open class EmployeesAdapter(var context: Context, var employee:ArrayList):BaseAdapter() < private class ViewHolder(row: View?) < var txt_user: TextView var user_job: TextView var img_user: ImageView var checBox: CheckBox init < this.txt_user = row?.findViewById(R.id.txt_user) as TextView this.img_user = row.findViewById(R.id.img_user) as ImageView this.user_job = row.findViewById(R.id.user_job) as TextView this.checBox = row.findViewById(R.id.checkBox) as CheckBox >> override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View < var view: View var viewHolder: ViewHolder if (convertView == null) < var layout = LayoutInflater.from(context) view = layout.inflate(R.layout.employee_list_item, parent, false) viewHolder = ViewHolder(view) view.tag = viewHolder >else < view = convertView viewHolder = view.tag as ViewHolder >var employees:EmployeesTest=getItem(position) as EmployeesTest viewHolder.txt_user.text = employees.nombre viewHolder.img_user.setImageResource(employees.profilePic) viewHolder.user_job.text = employees.cargo viewHolder.checBox.isChecked = false return view > override fun getItem(position: Int): Any < return employee[position] >override fun getItemId(position: Int): Long < return position.toLong() >override fun getCount(): Int < return employee.count() >>
class EditEmployeeFragment : Fragment() < var tv_name: TextView? = null var rel_main: RelativeLayout? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? < var view:View?=inflater. inflate(R.layout.edit_employee_fragment,container,false) var arrReports: ArrayList? = ArrayList() arrReports?.add(EmployeesTest("Heber","Desarrollador",R.drawable.img_user)) arrReports?.add(EmployeesTest("Mata","Desarrollador",R.drawable.img_user)) arrReports?.add(EmployeesTest("Ernesto","Desarrollador",R.drawable.img_user)) arrReports?.add(EmployeesTest("Toño","Desarrollador",R.drawable.img_user)) var recyclerView:RecyclerView=view?.findViewById(R.id.recycler_edit_employees) as RecyclerView recyclerView.layoutManager = LinearLayoutManager(this.context, LinearLayout.VERTICAL, false) recyclerView.adapter = EditEmployeesAdapter( arrReports!!) return view > >
stackoverflow is not for tutorial. please try your self to do something first. how this question is related to kotlin only? refer below libs github.com/AleBarreto/DragRecyclerView github.com/daimajia/AndroidSwipeLayout
I did try, but I made a mess and I prefered to post something «clean» to post the mess I did while doing my tests, sorry if it seemed that way, I only use stackoverflow when I´m really stuck thank’s for your comment, I asked here, because I have close to 3 hours trying to sort this out, and it ocurred to me, that maybe someone had the same need as me and implemented something, and instead of wasting another 3 hours I just asked, sometimes someone has another perspective of the problem, sorry if a bothered you, thanks so much for your help
Don’t worry no issue with that you are good. check those lib it will work in kotlin also so still you face any issue please ask here i will help you don’t worry
4 Answers 4
val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) < override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean < return false >override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) < noteViewModel.delete(noteAdapter.getNoteAt(viewHolder.adapterPosition)) Toast.makeText( this@MainActivity, getString(R.string.note_deleted), Toast.LENGTH_SHORT ).show() >> val itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback) itemTouchHelper.attachToRecyclerView(rvNote)
You need itemTouchHelper.
recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL)) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = simpleAdapter
val swipeHandler = object : SwipeToDeleteCallback(this) < override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) < val adapter = recyclerView.adapter as SimpleAdapter adapter.removeAt(viewHolder.adapterPosition) >> val itemTouchHelper = ItemTouchHelper(swipeHandler) itemTouchHelper.attachToRecyclerView(recyclerView)
SwipeToDeleteCallback
abstract class SwipeToDeleteCallback(context: Context) : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) < private val deleteIcon = ContextCompat.getDrawable(context, R.drawable.ic_delete_white_24) private val intrinsicWidth = deleteIcon.intrinsicWidth private val intrinsicHeight = deleteIcon.intrinsicHeight private val background = ColorDrawable() private val backgroundColor = Color.parseColor("#f44336") private val clearPaint = Paint().apply < xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) >override fun getMovementFlags(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?): Int < /** * To disable "swipe" for specific item return 0 here. * For example: * if (viewHolder?.itemViewType == YourAdapter.SOME_TYPE) return 0 * if (viewHolder?.adapterPosition == 0) return 0 */ if (viewHolder?.adapterPosition == 10) return 0 return super.getMovementFlags(recyclerView, viewHolder) >override fun onMove(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?, target: RecyclerView.ViewHolder?): Boolean < return false >override fun onChildDraw( c: Canvas?, recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) < val itemView = viewHolder.itemView val itemHeight = itemView.bottom - itemView.top val isCanceled = dX == 0f && !isCurrentlyActive if (isCanceled) < clearCanvas(c, itemView.right + dX, itemView.top.toFloat(), itemView.right.toFloat(), itemView.bottom.toFloat()) super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) return >// Draw the red delete background background.color = backgroundColor background.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom) background.draw(c) // Calculate position of delete icon val deleteIconTop = itemView.top + (itemHeight - intrinsicHeight) / 2 val deleteIconMargin = (itemHeight - intrinsicHeight) / 2 val deleteIconLeft = itemView.right - deleteIconMargin - intrinsicWidth val deleteIconRight = itemView.right - deleteIconMargin val deleteIconBottom = deleteIconTop + intrinsicHeight // Draw the delete icon deleteIcon.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom) deleteIcon.draw(c) super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) > private fun clearCanvas(c: Canvas?, left: Float, top: Float, right: Float, bottom: Float) < c?.drawRect(left, top, right, bottom, clearPaint) >>