243

Is there any widget like EditText which contains a cross button, or is there any property for EditText by which it is created automatically? I want the cross button to delete whatever text written in EditText.

Joel Christophel
  • 2,604
  • 4
  • 30
  • 49
Arun Badole
  • 10,977
  • 19
  • 67
  • 96
  • 2
    Doesn't appear to be any standard widget for it. But you find a few different approaches with a Google search for "android edittext clear button x". So I guess "clear buttons" is what they call it. Also, see this answer to a related question: http://stackoverflow.com/questions/4175398/clear-edittext-on-click/6235602#6235602 – HostileFork says dont trust SE Jun 15 '11 at 08:51
  • another question that is essentially a duplicate is *[implement uitextfield properties in android](http://stackoverflow.com/questions/6274021/implement-uitextfield-properties-in-android/)* – Alex Cohn May 11 '15 at 20:43
  • You can download source here: https://github.com/GhOsTTT/editTextXbutton have a nice day – Gökhan Musapaşaoğlu ヅ Jan 28 '14 at 08:38

18 Answers18

172

2020 solution via Material Design Components for Android:

Add Material Components to your gradle setup:

Look for latest version from here: https://maven.google.com/

implementation 'com.google.android.material:material:1.3.0'

or if you havent updated to using AndroidX libs, you can add it this way:

implementation 'com.android.support:design:28.0.0'

Then

<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/hint_text"
    app:endIconMode="clear_text">

  <com.google.android.material.textfield.TextInputEditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>

</com.google.android.material.textfield.TextInputLayout>

Pay attention to: app:endIconMode="clear_text"

As discussed here Material design docs

kevoroid
  • 5,052
  • 5
  • 34
  • 43
  • 20
    This should be the new accepted answer. In my case, I wasn't able to implement without updating to AndroidX libraries. – Ben Jun 20 '19 at 21:17
  • @Ben (thumbs up) – kevoroid Jun 25 '19 at 10:18
  • Please be sure to read through documentation as not all of the xml attributes are supported yet. You may have to look through the source or commit messages as those are sometimes where exact implementation details are. I had this type of issue for a custom endIcon. A commit message revealed that the xml attribute had no implementation backing it yet. Will have to use a different approach until implementation is finished – M. Smith Dec 04 '19 at 18:40
  • Best answer in 2020. – Sam Chen Apr 11 '20 at 04:01
  • does app:endIconMode="clear_text" is workign with `` ? can you please help me in same – Arbaz.in Apr 21 '20 at 09:26
  • @Arbaz.in Not sure to be honest, just make sure you're wrapping your EditText with "TextInputLayout", if it didnt work, then you need to replace your "AppCompatEditText" with "TextInputEditText". – kevoroid Apr 22 '20 at 06:13
  • can i have 2 endiconmode? – alfianrehanusa May 07 '20 at 14:29
  • @kevoroid when i use implementation 'com.google.android.material:material:1.1.0' some errors comming up, i used its latest version also but all of them causing some AAPT2 errors.What to do?? – KJEjava48 Apr 30 '21 at 06:57
  • Why is this input box so thick (almost twice as tall as regular EditText)? – Damn Vegetables Oct 13 '22 at 12:42
  • I'm using Material 1.5.0 and the icon doesn't show up – TheRealChx101 Feb 22 '23 at 19:28
  • Don't forget to set the tint of the icon! ;) – Seraphim's May 03 '23 at 10:17
171

Use the following layout:

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="9dp"
    android:padding="5dp">

    <EditText
        android:id="@+id/calc_txt_Prise"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="numberDecimal"  
        android:layout_marginTop="20dp"
        android:textSize="25dp"
        android:textColor="@color/gray"
        android:textStyle="bold"
        android:hint="@string/calc_txt_Prise"
        android:singleLine="true" />

    <Button
        android:id="@+id/calc_clear_txt_Prise"      
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:layout_gravity="right|center_vertical"
        android:background="@drawable/delete" />

</FrameLayout>

You can also use the button's id and perform whatever action you want on its onClickListener method.

lmaooooo
  • 3,364
  • 4
  • 19
  • 24
Jaydeep Khamar
  • 5,975
  • 3
  • 32
  • 30
  • 8
    this is a inefficient way of doing it. yanchenko's answer is right approach of using compound drawables. – numan salati Apr 10 '13 at 15:48
  • 4
    If you happen to choose this solution and notice that the image is stretched a lot too much, you should probably use an ImageButton instead of a regular Button. – personne3000 Apr 23 '13 at 14:53
  • 5
    While this solution is "inefficient", it's a lot more accessible for blind users. Using a drawable will force your users to perform very complicated operations to clearing the text - something that seeing users can do quickly with the X button. – Daniel Monteiro Sep 02 '15 at 20:18
  • 2
    What's the inefficiency about this? – Denny Feb 04 '18 at 19:13
121

If you happen to use DroidParts, I've just added ClearableEditText.

Here's what it looks like with a custom background & clear icon set to abs__ic_clear_holo_light from ActionBarSherlock:

enter image description here

yanchenko
  • 56,576
  • 33
  • 147
  • 165
  • 12
    Best solution because the class extends `EditText`. Thx @yanchenko – tbruyelle May 05 '13 at 16:45
  • This is good, but when I tap on the icon, it clears the text but also shows the "paste" button, how strange is that? – stephane k. Jul 08 '13 at 09:48
  • 2
    @stephanek. I've fixed this in the develop branch, will be part of the 1.4.3 release. – yanchenko Jul 16 '13 at 22:22
  • Keep in mind that if you use this solution and also call [TextView.setError(...)](https://developer.android.com/reference/android/widget/TextView.html#setError(java.lang.CharSequence)) you will have to reset the right drawable after clearing the error text. – jush Jan 08 '14 at 09:01
  • 4
    Thanks! It would be really cool though if you could also include a ClearableAutoCompleteTextView in DroidParts. For others users that also try to do this: use DroidParts library, copy the code from ClearableEditText and just extend AutoCompleteTextView. – RobinDeCroon Feb 16 '14 at 15:13
  • 2
    This is bomb! You can also use it standalone changing the TextWatcherAdapter dependency with a normal TextWatcher. – Pimentoso Dec 17 '14 at 14:02
  • @yanchenko Hey, I've just been using your clearableEditText and found some abnormal response to touch events. If you start by pressing the x then moving your finger to the right, outside of the edit text, the field would clear. To resolve this I changed a bit of code in your on touch method so that it only clears touches that start and end within the bounds of the X. – Jack.Ramsden Jan 12 '16 at 15:05
  • @yanchenko boolean tappedX = event.getX() > (getWidth() - getPaddingRight() - xD.getIntrinsicWidth()) && event.getX() < getWidth() && event.getY() > 0 // The x any y pos start in the bottom left of the view. && event.getY() < getHeight(); // So between 0 and height(of the edit text) is the bounds of the view. – Jack.Ramsden Jan 12 '16 at 15:07
  • 1
    @yanchenko Had a look at your implementation. Seems like there is a bit of a trade off between the accepted touch area being rather small and having an edit text with a larger than default height accepting touch events all along the y axis within the edit text. Your implementation was the former and mine the latter. In similar circumstances would you recommend doing the same? i.e. go for a smaller hit box that could be miss-pressed or have a larger hit box, where, with an expanding or larger edit text the presses could be well outside the bounds of the drawable. – Jack.Ramsden Jan 15 '16 at 09:12
  • I have a xamarin solution here : https://stackoverflow.com/questions/46069323/clearableedittext-for-xamarin-android/49494031#49494031 – FreakyAli Mar 26 '18 at 14:45
  • Including the latest version (3.2.5) of `droidparts` works, but using the `ClearableEditText` like in the example code does not work for me. – dsalaj Jul 26 '19 at 07:10
  • @yanchenko I have a datepicker edittext field where android:focusable="false" , how can i use this for such fields???pls help – KJEjava48 Apr 30 '21 at 06:54
  • How to install with Gradle: `implementation 'org.droidparts:droidparts-misc:3.2.5'` – mathematics-and-caffeine Jul 28 '21 at 16:05
38

This is a kotlin solution. Put this helper method in some kotlin file-

fun EditText.setupClearButtonWithAction() {

    addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(editable: Editable?) {
            val clearIcon = if (editable?.isNotEmpty() == true) R.drawable.ic_clear else 0
            setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0)
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit
    })

    setOnTouchListener(View.OnTouchListener { _, event ->
        if (event.action == MotionEvent.ACTION_UP) {
            if (event.rawX >= (this.right - this.compoundPaddingRight)) {
                this.setText("")
                return@OnTouchListener true
            }
        }
        return@OnTouchListener false
    })
}

And then use it as following in the onCreate method and you should be good to go-

yourEditText.setupClearButtonWithAction()

BTW, you have to add R.drawable.ic_clear or the clear icon at first. This one is from google- https://fonts.google.com/icons?selected=Material%20Icons%20Outlined%3Aclear%3A

Gulshan
  • 3,611
  • 5
  • 35
  • 46
  • If you insert `this.clearFocus()` before the return true statement, you can listen to this event on the EditText caller with the `onFocusChange` listener – Joost Schepel Mar 25 '20 at 09:24
  • Great it's wotking , only issue is i set drawable left icon in AppCompatEditText and it'll remove when i call this funcion can you please tell me what the issue? – Arbaz.in Apr 21 '20 at 09:42
  • @Arbaz.in It is because of calling method `setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0)` . You can pass the left drawable icon id as a new param to this function and put it in the call. – Gulshan Apr 21 '20 at 17:39
  • @Gulshan i have done same still remove that drawable – Arbaz.in Apr 22 '20 at 07:07
24

Android's support libarary has a SearchView class that does exactly this. (Not derrived from EditText though, so have to use a SearchView.OnQueryTextListener instead of a TextWatcher)

Search view with no text (and hint text "Search")

enter image description here

Use in XML like so:

  <android.support.v7.widget.SearchView
            android:id="@+id/searchView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:iconifiedByDefault="false"
            android:queryHint="@string/SearchHint"
            app:iconifiedByDefault="false"
            app:queryHint="@string/SearchHint" />
Diederik
  • 5,536
  • 3
  • 44
  • 60
15
Drawable x = getResources().getDrawable(R.drawable.x);
x.setBounds(0, 0, x.getIntrinsicWidth(), x.getIntrinsicHeight());
mEditText.setCompoundDrawables(null, null, x, null);

where, x is:

enter image description here

Eamorr
  • 9,872
  • 34
  • 125
  • 209
  • 9
    Still we need to assign an onClickListener right? A quick search gave me [this](http://stackoverflow.com/questions/3554377/handling-click-events-on-a-drawable-within-an-edittext). Guess better solution is to go with the Framelayout one. Thanks though! – VenoM Mar 22 '13 at 09:32
13

For drawable resource you can use standard android images :

web archive for http://androiddrawables.com/Menu.html

For example :

android:background="@android:drawable/ic_menu_close_clear_cancel"
0x8BADF00D
  • 7,138
  • 2
  • 41
  • 34
  • 1
    FWIW, the linked domain is dead and has been domain-squatted. This is the last update of what it looked like, showing 4.1-7.1. Very nice :) https://web.archive.org/web/20171127224252/http://www.androiddrawables.com/Menu.html – i336_ Oct 06 '21 at 17:38
7

If you don't want to use custom views or special layouts, you can use 9-patch to make the (X) button .

Example: http://postimg.org/image/tssjmt97p/ (I don't have enough points to post images on StackOverflow)

The intersection of the right and bottom black pixels represent the content area. Anything outside of that area is padding. So to detect that the user clicked on the x you can set a OnTouchListener like so:

editText.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_UP){
            if (motionEvent.getX()>(view.getWidth()-view.getPaddingRight())){
                ((EditText)view).setText("");
            }
        }
        return false;
    }
});

According to your needs this solution can work better in some cases. I prefer to keep my xml less complicated. This also helps if you want to have an icon on the left, as you can simply include it in the 9 patch.

Gary Chen
  • 248
  • 2
  • 14
Andrei Tudor Diaconu
  • 2,157
  • 21
  • 26
  • Use `motionEvent.getRawX()`. – CoolMind Oct 25 '21 at 13:31
  • @CoolMind Wouldn't `motionEvent.getRawX()` return absolute coordinates (relative to the screen)? This solution needs the coordinates to be relative to the view, which `motionEvent.getX()` does. – Andrei Tudor Diaconu Nov 28 '21 at 10:50
  • Maybe you are right, but in my case `getRawX()` helped. Also two solutions on this page use `rawX()`. But I agree with you, it depends on situation. – CoolMind Nov 29 '21 at 06:26
7

Just put close cross like drawableEnd in your EditText:

<EditText
     ...
    android:drawableEnd="@drawable/ic_close"
    android:drawablePadding="8dp"
     ... />

and use extension to handle click (or use OnTouchListener directly on your EditText):

fun EditText.onDrawableEndClick(action: () -> Unit) {
    setOnTouchListener { v, event ->
        if (event.action == MotionEvent.ACTION_UP) {
            v as EditText
            val end = if (v.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL)
                v.left else v.right
            if (event.rawX >= (end - v.compoundPaddingEnd)) {
                action.invoke()
                return@setOnTouchListener true
            }
        }
        return@setOnTouchListener false
    }
}

extension usage:

editText.onDrawableEndClick {
    // TODO clear action
    etSearch.setText("")
}
Francis
  • 6,788
  • 5
  • 47
  • 64
6

Clear text:

"Text field with a clear text trailing icon."

If set, an icon is displayed when text is present and pressing it clears the input text.

    ...
    app:endIconMode="clear_text">
​
    ...
​
</com.google.android.material.textfield.TextInputLayout>

I leave it here:

material.io

Example
example

Aliqua
  • 723
  • 7
  • 21
user12927542
  • 151
  • 2
  • 2
4

I did the UI part like below:

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="50dp"
    android:layout_marginTop="9dp"
    android:padding="5dp">

    <EditText
        android:id="@+id/etSearchToolbar"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:textSize="13dp"
        android:padding="10dp"
        android:textColor="@android:color/darker_gray"
        android:textStyle="normal"
        android:hint="Search"
        android:imeOptions="actionSearch"
        android:inputType="text"
        android:background="@drawable/edittext_bg"
        android:maxLines="1" />

    <ImageView
        android:id="@+id/ivClearSearchText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginRight="6dp"
        android:src="@drawable/balloon_overlay_close"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>

edittext_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/rounded_edittext_focused.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:shape="rectangle" >

    <solid android:color="#FFFFFF" />

    <stroke
        android:width="1dp"
        android:color="#C9C9CE" />

    <corners
        android:bottomLeftRadius="15dp"
        android:bottomRightRadius="15dp"
        android:topLeftRadius="15dp"
        android:topRightRadius="15dp" />

</shape>

balloon_overlay_close.pngenter image description here

Cross/Clear button hide/show:

searchBox.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        if(charSequence.length() > 0){
            clearSearch.setVisibility(View.VISIBLE);
        }else{
            clearSearch.setVisibility(View.GONE);
        }
    }

    @Override
    public void afterTextChanged(Editable editable) {}
});

Handle search stuffs (i.e when user clicks search from soft key board)

searchBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_SEARCH) {
            String contents = searchBox.getText().toString().trim();
            if(contents.length() > 0){
                //do search

            }else{
                //if something to do for empty edittext
            }

            return true;
        }
        return false;
    }
});

Clear/Cross button

clearSearch.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        searchBox.setText("");
    }
});
Gary Chen
  • 248
  • 2
  • 14
Ranjit
  • 5,130
  • 3
  • 30
  • 66
3

Here is complete library with the widget: https://github.com/opprime/EditTextField

To use it you should add the dependency:

compile 'com.optimus:editTextField:0.2.0'

In the layout.xml file you can play with the widget settings:

xmlns:app="http://schemas.android.com/apk/res-auto"
  • app:clearButtonMode,can has such values: never always whileEditing unlessEditing

  • app:clearButtonDrawable

Sample in action:

enter image description here

Kirill Vashilo
  • 1,559
  • 1
  • 18
  • 27
2

Use

android:drawableRight="@android:drawable/ic_input_delete"
HimalayanCoder
  • 9,630
  • 6
  • 59
  • 60
1

You can use this snippet with Jaydip answer for more than one button. just call it after getting a reference to the ET and Button Elements. I used vecotr button so you have to change the Button element to ImageButton:

private void setRemovableET(final EditText et, final ImageButton resetIB) {

        et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus && et.getText().toString().length() > 0)
                    resetIB.setVisibility(View.VISIBLE);
                else
                    resetIB.setVisibility(View.INVISIBLE);
            }
        });

        resetIB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                et.setText("");
                resetIB.setVisibility(View.INVISIBLE);
            }
        });

        et.addTextChangedListener(new TextWatcher() {
            @Override
            public void afterTextChanged(Editable s) {}
            @Override
            public void beforeTextChanged(CharSequence s, int start,
                                          int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start,
                                      int before, int count) {
                if(s.length() != 0){
                    resetIB.setVisibility(View.VISIBLE);
                }else{
                    resetIB.setVisibility(View.INVISIBLE);
                }
            }
        });
    }
sivi
  • 10,654
  • 2
  • 52
  • 51
0

If you are in frame layout or you can create a frame layout I tried another approach....

<TextView
    android:id="@+id/inputSearch"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableRight="@drawable/ic_actionbar"
    android:layout_alignParentBottom="true"
    android:layout_toRightOf="@+id/back_button"/>

<Button
    android:id="@+id/clear_text_invisible_button"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:layout_gravity="right|center_vertical"
    android:background="@color/transparent"
    android:layout_alignBaseline="@+id/inputSearch"
    android:layout_alignBottom="@+id/inputSearch"
    android:layout_alignRight="@+id/inputSearch"
    android:layout_alignEnd="@+id/inputSearch"
    android:layout_marginRight="13dp"
    />

This is an edit text where I put a cross icon as a right drawable and than UPON it I put a transparent button which clears text.

0
    <EditText
    android:id="@+id/idSearchEditText"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dimen_40dp"
    android:drawableStart="@android:drawable/ic_menu_search"
    android:drawablePadding="8dp"
    android:ellipsize="start"
    android:gravity="center_vertical"
    android:hint="Search"
    android:imeOptions="actionSearch"
    android:inputType="text"
    android:paddingStart="16dp"
    android:paddingEnd="8dp"
/>

EditText mSearchEditText = findViewById(R.id.idSearchEditText);
mSearchEditText.addTextChangedListener(this);
mSearchEditText.setOnTouchListener(this);


@Override
public void afterTextChanged(Editable aEditable) {
    int clearIcon = android.R.drawable.ic_notification_clear_all;
    int searchIcon = android.R.drawable.ic_menu_search;
    if (aEditable == null || TextUtils.isEmpty(aEditable.toString())) {
        clearIcon = 0;
        searchIcon = android.R.drawable.ic_menu_search;
    } else {
        clearIcon = android.R.drawable.ic_notification_clear_all;
        searchIcon = 0;
    }
    Drawable leftDrawable =  null;
    if (searchIcon != 0) {
        leftDrawable = getResources().getDrawable(searchIcon);
    }
    Drawable rightDrawable = null;
    if (clearIcon != 0) {
        rightDrawable = getResources().getDrawable(clearIcon);
    }

    mSearchEditText.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, rightDrawable, null);
}


@Override
public boolean onTouch(View aView, MotionEvent aEvent) {
    if (aEvent.getAction() == MotionEvent.ACTION_UP){
        if (aEvent.getX() > ( mSearchEditText.getWidth() - 
         mSearchEditText.getCompoundPaddingEnd())){
            mSearchEditText.setText("");
        }
    }
    return false;
}
0

Here is the simple complete solution in kotlin.

This whole layout will be your search bar

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="35dp"
        android:layout_margin="10dp"
        android:background="@drawable/your_desired_drawable">

        <EditText
            android:id="@+id/search_et"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_toStartOf="@id/clear_btn"
            android:background="@null"
            android:hint="search..."
            android:imeOptions="actionSearch"
            android:inputType="text"
            android:maxLines="1"
            android:paddingStart="15dp"
            android:paddingEnd="10dp" />

        <ImageView
            android:id="@+id/clear_btn"
            android:layout_width="20dp"
            android:layout_height="match_parent"
            android:layout_alignParentEnd="true"
            android:layout_centerInParent="true"
            android:layout_marginEnd="15dp"
            android:visibility="gone"
            android:src="@drawable/ic_baseline_clear_24"/>

    </RelativeLayout>

Now this is the functionality of clear button, paste this code in onCreate method.

search_et.addTextChangedListener(object: TextWatcher {
            override fun beforeTextChanged(s:CharSequence, start:Int, count:Int, after:Int) {
            }
            override fun onTextChanged(s:CharSequence, start:Int, before:Int, count:Int) {
            }
            override fun afterTextChanged(s: Editable) {
                if (s.isNotEmpty()){
                    clear_btn.visibility = VISIBLE
                    clear_btn.setOnClickListener {
                        search_et.text.clear()
                    }
                }else{
                    clear_btn.visibility = GONE
                }
            }
        })
Stackoverflower
  • 292
  • 4
  • 17
0

It's a best way to create custom clearable edittext with close icon and gettextcleanlistener

class EditTextWithClear : AppCompatEditText {

constructor(context: Context) : super(context)

constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)

constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
    context,
    attributeSet,
    defStyleAttr
)

private val blackClearDrawable =
    ResourcesCompat.getDrawable(resources, R.drawable.ic_clear_text, null) as Drawable
private val opaqueClearDrawable =
    ResourcesCompat.getDrawable(resources, R.drawable.ic_clear_text, null) as Drawable

private var clearButtonImage: Drawable = opaqueClearDrawable
private var onTextClearListener: OnTextClearListener? = null

fun setOnTextClearListener(onTextClearListener: OnTextClearListener) {
    this.onTextClearListener = onTextClearListener
}

private fun showClearButton() {
    setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, clearButtonImage, null)
}

private fun hideClearButton() {
    setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null)
}

@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
    if (isClearButtonVisible() && wasClearButtonTouched(event)) {
        onClearButtonTouched(event)
        return true
    }

    return super.onTouchEvent(event)
}

override fun onTextChanged(
    text: CharSequence?,
    start: Int,
    lengthBefore: Int,
    lengthAfter: Int
) {
    if (text?.isNotEmpty() == true) {
        showClearButton()
    } else {
        onTextClearListener?.onTextClearListener()
        hideClearButton()
    }
}

private fun isClearButtonVisible(): Boolean {
    return compoundDrawablesRelative[2] != null
}

private fun wasClearButtonTouched(event: MotionEvent): Boolean {
    val isClearButtonAtTheStart = layoutDirection == View.LAYOUT_DIRECTION_RTL

    return if (isClearButtonAtTheStart) {

        val clearButtonEnd = paddingStart + clearButtonImage.intrinsicWidth
        event.x < clearButtonEnd

    } else {

        val clearButtonStart = width - clearButtonImage.intrinsicWidth - paddingEnd
        event.x > clearButtonStart

    }
}

private fun onClearButtonTouched(event: MotionEvent) {
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            clearButtonImage = blackClearDrawable
            showClearButton()
        }
        MotionEvent.ACTION_UP -> {
            clearButtonImage = opaqueClearDrawable
            text?.clear()
            hideClearButton()
        }
    }
}

interface OnTextClearListener {
    fun onTextClearListener()
}

/*
This code use your activity and fragment
editext.setOnTextClearListener(object : EditTextWithClear.OnTextClearListener{
    override fun onTextClearListener() {
        //perform action when empty your edittext
    }
})*/}

Xml code

<com.example.clearbaleedittext.utility.EditTextWithClear
    android:id="@+id/etEditext"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/dp_12"
    android:background="@color/transparent"
    android:fontFamily="@font/helvetica_normal"
    android:inputType="text"
    android:maxLines="1"
    android:paddingHorizontal="@dimen/dp_12"
    android:paddingVertical="@dimen/dp_12"
    android:textSize="@dimen/sp_16"
    />
Sumit Ojha
  • 283
  • 2
  • 8