¿Cómo crear EditText con el botón cruzado (x) al final?

198

¿Hay algún widget como el EditTextque contiene un botón cruzado, o hay alguna propiedad para la EditTextcual se crea automáticamente? Quiero que el botón cruzado elimine cualquier texto escrito EditText.

Arun Badole
fuente
2
No parece ser ningún widget estándar para ello. Pero encuentra algunos enfoques diferentes con una búsqueda en Google para "Android edittext clear button x". Así que supongo que "botones claros" es como lo llaman. Además, vea esta respuesta a una pregunta relacionada: stackoverflow.com/questions/4175398/clear-edittext-on-click/…
HostileFork dice que no confíe en SE
Puede descargar la fuente aquí: github.com/GhOsTTT/editTextXbutton tenga un buen día
Gökhan Musapaşaoğlu ヅ
Otra pregunta que es esencialmente un duplicado es implementar propiedades uitextfield en Android
Alex Cohn,

Respuestas:

166

Use el siguiente diseño:

<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>

También puede usar la identificación del botón y realizar cualquier acción que desee en su método onClickListener.

Jaydeep Khamar
fuente
8
Esta es una forma ineficiente de hacerlo. La respuesta de Yanchenko es el enfoque correcto del uso de elementos dibujables compuestos.
numan salati
44
Si elige esta solución y observa que la imagen se estira demasiado, probablemente debería usar un ImageButton en lugar de un Botón normal.
personne3000
3
Si bien esta solución es "ineficiente", es mucho más accesible para usuarios ciegos. El uso de un dibujable obligará a sus usuarios a realizar operaciones muy complicadas para borrar el texto, algo que los usuarios pueden hacer rápidamente con el botón X.
Daniel Monteiro
2
¿Cuál es la ineficiencia de esto?
Denny
121

Si utiliza DroidParts , acabo de agregar ClearableEditText .

Esto es lo que parece con un fondo personalizado y un ícono claro configurado abs__ic_clear_holo_lightdesde ActionBarSherlock :

ingrese la descripción de la imagen aquí

Yanchenko
fuente
11
La mejor solución porque la clase se extiende EditText. Thx @yanchenko
tbruyelle
2
@stephanek. He solucionado esto en la rama de desarrollo, será parte de la versión 1.4.3.
yanchenko
44
¡Gracias! Sin embargo, sería realmente genial si también pudiera incluir un ClearableAutoCompleteTextView en DroidParts. Para otros usuarios que también intentan hacer esto: usar la biblioteca DroidParts, copiar el código de ClearableEditText y simplemente extender AutoCompleteTextView.
RobinDeCroon
2
Esta es una bomba! También puede usarlo de forma independiente cambiando la dependencia TextWatcherAdapter con un TextWatcher normal.
Pimentoso
1
@yanchenko Echó un vistazo a su implementación. Parece que hay una pequeña compensación entre el área táctil aceptada que es bastante pequeña y que tiene un texto de edición con una altura mayor que la predeterminada que acepta eventos táctiles a lo largo del eje y dentro del texto de edición. Su implementación fue la primera y la mía la segunda. En circunstancias similares, ¿recomendarías hacer lo mismo? es decir, vaya a un cuadro de golpe más pequeño que podría presionarse mal o tener un cuadro de golpe más grande, donde, con un texto de edición expandido o más grande, las prensas podrían estar muy fuera de los límites del dibujo.
Jack.Ramsden
64

Solución 2020 a través de Componentes de diseño de materiales para Android:

Agregue componentes de material a su configuración de gradle:

Busque la última versión desde aquí: https://maven.google.com/

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

o si no ha actualizado el uso de las bibliotecas de AndroidX, puede agregarlo de esta manera:

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

Luego

<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>

Presta atención a: app: endIconMode = "clear_text"

Como se discutió aquí Documentos de diseño de materiales

kevoroid
fuente
10
Esta debería ser la nueva respuesta aceptada. En mi caso, no pude implementar sin actualizar a las bibliotecas de AndroidX.
Ben
@Ben (pulgar hacia arriba)
kevoroid
Asegúrese de leer toda la documentación, ya que aún no se admiten todos los atributos xml. Es posible que tenga que mirar a través de la fuente o enviar mensajes, ya que a veces es donde se encuentran los detalles exactos de implementación. Tuve este tipo de problema para un endIcon personalizado. Un mensaje de confirmación reveló que el atributo xml aún no tenía una implementación que lo respaldara. Tendrá que usar un enfoque diferente hasta que finalice la implementación
M. Smith
La mejor respuesta en 2020.
Sam Chen
¿app: endIconMode = "clear_text" es workign con <androidx.appcompat.widget.AppCompatEditText/>? puede usted por favor me ayude en la misma
Arbaz.in
32

Esta es una solución de Kotlin. Ponga este método auxiliar en algún archivo kotlin

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
    })
}

Y luego úsalo de la siguiente manera en el onCreatemétodo y deberías estar listo para comenzar.

yourEditText.setupClearButtonWithAction()

Por cierto, R.drawable.ic_clearprimero debes agregar o borrar el ícono. Este es de google- https://material.io/tools/icons/?icon=clear&style=baseline

Gulshan
fuente
Si inserta this.clearFocus()antes de la declaración de retorno verdadero, puede escuchar este evento en la persona que llama EditText con el onFocusChangeoyente
Joost Schepel
Genial es wotking, el único problema es que configuré el icono izquierdo dibujable en AppCompatEditText y se eliminará cuando llame a esta función, ¿podría decirme cuál es el problema?
Arbaz.in
@ Arbaz.in Es por el método de llamada setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0). Puede pasar el ID del icono dibujable izquierdo como un nuevo parámetro a esta función y ponerlo en la llamada.
Gulshan
@Gulshan, he hecho lo mismo, todavía
elimino
20

La biblioteca de soporte de Android tiene una SearchViewclase que hace exactamente esto. (Sin EditTextembargo, no está derivado de , así que debe usar a en SearchView.OnQueryTextListenerlugar de a TextWatcher)

Vista de búsqueda sin texto (y texto de sugerencia "Buscar")

ingrese la descripción de la imagen aquí

Usar en XML así:

  <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
fuente
16
Drawable x = getResources().getDrawable(R.drawable.x);
x.setBounds(0, 0, x.getIntrinsicWidth(), x.getIntrinsicHeight());
mEditText.setCompoundDrawables(null, null, x, null);

donde, x es:

ingrese la descripción de la imagen aquí

Eamorr
fuente
8
¿Todavía tenemos que asignar un onClickListener correcto? Una búsqueda rápida me dio esto . Supongo que la mejor solución es ir con Framelayout. Gracias sin embargo!
VenoM
6

Si no desea usar vistas personalizadas o diseños especiales, puede usar 9 parches para hacer el botón (X).

Ejemplo: http://postimg.org/image/tssjmt97p/ (No tengo suficientes puntos para publicar imágenes en StackOverflow)

La intersección de los píxeles negros derecho e inferior representa el área de contenido. Cualquier cosa fuera de esa área es relleno. Entonces, para detectar que el usuario hizo clic en la x, puede configurar un OnTouchListener de esta manera:

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;
            }
        });

Según sus necesidades, esta solución puede funcionar mejor en algunos casos. Prefiero mantener mi xml menos complicado. Esto también ayuda si desea tener un icono a la izquierda, ya que simplemente puede incluirlo en el parche 9.

Andrei Tudor Diaconu
fuente
4

Hice la parte de la interfaz de usuario como a continuación:

<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"?>

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

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

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

balloon_overlay_close.pngingrese la descripción de la imagen aquí

Botón Cruz / Borrar ocultar / mostrar:

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) {}
    });

Manejar material de búsqueda (es decir, cuando el usuario hace clic en buscar desde el tablero de teclas programables)

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;
        }
    });`

Botón Borrar / Cruz

  clearSearch.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            searchBox.setText("");
        }
    });
Ranjit
fuente
2

Utilizar

android:drawableRight="@android:drawable/ic_input_delete"
HimalayaCoder
fuente
2

Aquí hay una biblioteca completa con el widget: https://github.com/opprime/EditTextField

Para usarlo debes agregar la dependencia:

compile 'com.optimus:editTextField:0.2.0'

En el archivo layout.xml puedes jugar con la configuración del widget:

xmlns:app="http://schemas.android.com/apk/res-auto"
  • aplicación: clearButtonMode, puede tener tales valores: nunca siempre whileEditing a menos que se edite

  • aplicación: clearButtonDrawable

Muestra en acción:

ingrese la descripción de la imagen aquí

Kirill Vashilo
fuente
2

Simplemente ponga una cruz cerca como drawableEnden su EditText:

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

y use la extensión para manejar el clic (o use OnTouchListenerdirectamente en su 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
    }
}

uso de extensión:

editText.onDrawableEndClick {
    // TODO clear action
    etSearch.setText("")
}
Francisco
fuente
1

Puede usar este fragmento con la respuesta de Jaydip para más de un botón. simplemente llámelo después de obtener una referencia a ET y Button Elements. Usé el botón vecotr, así que debes cambiar el elemento Button a 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
fuente
0

Si está en el diseño del marco o puede crear un diseño del marco, intenté otro enfoque ...

<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"
    />

Este es un texto de edición en el que pongo un ícono de cruz como un dibujo derecho y, luego, coloco un botón transparente que borra el texto.

Kleand Sherali
fuente
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;
}
Anupam Singh
fuente