How to make long clickable clear button in Kotlin Android Studio

Viewed 220

I have a calculator written on Kotlin which has a clear button,
and I want to make this clear button: if you press on it, it starts deleting text from string,
and every second it deletes faster and faster, like in google calculator
Clear button Kotlin code:

buttonClear.setOnClickListener {
    string.text = string.text.toString().droplast(1)
}

Android Studio front end button code:

<Button
    android:id="@+id/buttonClear"
    android:longClickable="true"
    android:text="C"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintVertical_bias="1.0" />

Full code on github

1 Answers

I made a sample project. You can change parameters in code so this function can delete characters faster/slower etc.

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    >
    
    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textMultiLine"
        android:text="@string/longStringTest"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Clear"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt:

import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.MotionEvent
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*


private const val charsDeletePerTimeStart = 1 // number of chars that will be deleted at the beginning 
private const val charsDeletePerTimeIncrement = 1 // number of chars that will increase number of deleting per `timePeriod` 
private const val timePeriod = 100L //time period in milliseconds, every 100ms chars will be deleted  

class MainActivity : AppCompatActivity()
{
    private val handler: Handler = Handler()
    private var charsToDelete = charsDeletePerTimeStart //actual number of deleting chars


    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        fun deleteChars() // this function delete last characters from EditText and increment `timePeriod`
        {
            editText.setText(editText.text.toString().dropLast(charsToDelete))
            Log.d("MyTag", "Deleted chars $charsToDelete")
            charsToDelete += charsDeletePerTimeIncrement
        }

        button.setOnTouchListener { _, e -> // setOnTouchListener, this will allow to start deleting chars
            if (e != null)
            {
                when (e.action)
                {
                    MotionEvent.ACTION_DOWN -> //click -> start deleting
                    {
                        charsToDelete = charsDeletePerTimeStart
                        deleteChars()            
                        handler.postDelayed(object : Runnable
                                            {
                                                override fun run()
                                                {
                                                    deleteChars()
                                                    handler.postDelayed(this, timePeriod)
                                                }
                                            }, timePeriod)
                    }
                    MotionEvent.ACTION_UP -> // stop -> clear handler
                    {
                        handler.removeCallbacksAndMessages(null)
                    }
                }
            }
            return@setOnTouchListener true
        }
    }
}

Result (logcat). Every ~100ms chars are deleted and every time it is one char more.

00:46:59.080  -  Deleted chars 1
00:46:59.189  -  Deleted chars 2
00:46:59.297  -  Deleted chars 3
00:46:59.406  -  Deleted chars 4
00:46:59.513  -  Deleted chars 5 // Here I stop deleting
00:47:02.957  -  Deleted chars 1 // start again
00:47:03.063  -  Deleted chars 2
00:47:03.170  -  Deleted chars 3
00:47:03.276  -  Deleted chars 4
00:47:03.381  -  Deleted chars 5
00:47:03.486  -  Deleted chars 6
Related