Comment créer EditText avec le bouton croix (x) à la fin de celui-ci?

198

Existe-t-il un widget comme celui EditTextqui contient un bouton croisé, ou existe-t-il une propriété pour EditTextlaquelle il est créé automatiquement? Je veux que le bouton en croix supprime le texte écrit EditText.

Arun Badole
la source
2
Ne semble pas être un widget standard pour cela. Mais vous trouvez quelques approches différentes avec une recherche Google pour "android edittext clear button x". Donc je suppose que les "boutons clairs" sont ce qu'ils appellent. Voir également cette réponse à une question connexe: stackoverflow.com/questions/4175398/clear-edittext-on-click/…
HostileFork dit de ne pas faire confiance au SE
Vous pouvez télécharger la source ici: github.com/GhOsTTT/editTextXbutton passez une bonne journée
Gökhan Musapaşaoğlu
une autre question qui est essentiellement un doublon est la mise en œuvre des propriétés uitextfield dans Android
Alex Cohn

Réponses:

166

Utilisez la disposition suivante:

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

Vous pouvez également utiliser l'ID du bouton et effectuer l'action que vous souhaitez sur sa méthode onClickListener.

Jaydeep Khamar
la source
8
c'est une façon inefficace de le faire. La réponse de Yanchenko est la bonne approche de l'utilisation des étirables composites.
numan salati
4
Si vous choisissez cette solution et que vous remarquez que l'image est trop étirée, vous devriez probablement utiliser un ImageButton au lieu d'un Button normal.
personne3000
3
Bien que cette solution soit "inefficace", elle est beaucoup plus accessible aux utilisateurs aveugles. L'utilisation d'un dessin obligera vos utilisateurs à effectuer des opérations très compliquées pour effacer le texte - quelque chose que voir les utilisateurs peut faire rapidement avec le bouton X.
Daniel Monteiro
2
Quelle est l'inefficacité à ce sujet?
Denny
121

S'il vous arrive d'utiliser DroidParts , je viens d'ajouter ClearableEditText .

Voici à quoi cela ressemble avec un arrière-plan personnalisé et une icône claire définie à abs__ic_clear_holo_lightpartir d' ActionBarSherlock :

entrez la description de l'image ici

yanchenko
la source
11
Meilleure solution car la classe s'étend EditText. Thx @yanchenko
tbruyelle
2
@stephanek. J'ai corrigé cela dans la branche develop, fera partie de la version 1.4.3.
yanchenko
4
Merci! Ce serait vraiment cool si vous pouviez également inclure un ClearableAutoCompleteTextView dans DroidParts. Pour les autres utilisateurs qui essaient également de le faire: utilisez la bibliothèque DroidParts, copiez le code de ClearableEditText et étendez simplement AutoCompleteTextView.
RobinDeCroon
2
C'est de la bombe! Vous pouvez également l'utiliser de manière autonome en modifiant la dépendance TextWatcherAdapter avec un TextWatcher normal.
Pimentoso
1
@yanchenko Jetez un œil à votre implémentation. Il semble qu'il y ait un certain compromis entre la zone tactile acceptée étant plutôt petite et ayant un texte d'édition avec une hauteur plus grande que la hauteur par défaut acceptant les événements tactiles tout le long de l'axe y dans le texte d'édition. Votre mise en œuvre était la première et la mienne la seconde. Dans des circonstances similaires, recommanderiez-vous de faire de même? c'est-à-dire optez pour une petite zone de hit qui pourrait être mal pressée ou avoir une plus grande zone de hit, où, avec un texte d'édition élargi ou plus grand, les pressions pourraient être bien en dehors des limites du dessinable.
Jack.Ramsden
64

Solution 2020 via Material Design Components pour Android:

Ajoutez des composants de matériau à votre configuration de gradle:

Recherchez la dernière version à partir d'ici: https://maven.google.com/

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

ou si vous n'avez pas mis à jour l'utilisation des bibliothèques AndroidX, vous pouvez l'ajouter de cette façon:

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

ensuite

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

Faire attention à: app: endIconMode = "clear_text"

Comme discuté ici Documents de conception de matériaux

kevoroid
la source
10
Ce devrait être la nouvelle réponse acceptée. Dans mon cas, je n'ai pas pu implémenter sans mettre à jour les bibliothèques AndroidX.
Ben
@Ben (pouce levé)
kevoroid
Veuillez vous assurer de lire la documentation car tous les attributs xml ne sont pas encore pris en charge. Vous devrez peut-être parcourir la source ou valider les messages car ce sont parfois les détails exacts de l'implémentation. J'ai eu ce type de problème pour un endIcon personnalisé. Un message de validation a révélé que l'attribut xml n'avait pas encore d'implémentation le soutenant. Devra utiliser une approche différente jusqu'à la fin de la mise en œuvre
M. Smith
Meilleure réponse en 2020.
Sam Chen
l'application: endIconMode = "clear_text" fonctionne-t-elle avec <androidx.appcompat.widget.AppCompatEditText/>? pouvez-vous m'aider s'il vous plait
Arbaz.in
32

Ceci est une solution kotlin. Mettez cette méthode d'assistance dans un fichier 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
    })
}

Et puis utilisez-le comme suit dans la onCreateméthode et vous devriez être bon pour aller-

yourEditText.setupClearButtonWithAction()

BTW, vous devez d'abord ajouter R.drawable.ic_clearou l'icône claire. Celui-ci est de google- https://material.io/tools/icons/?icon=clear&style=baseline

Gulshan
la source
Si vous insérez this.clearFocus()avant l'instruction return true, vous pouvez écouter cet événement sur l'appelant EditText avec l' onFocusChangeauditeur
Joost Schepel
Super c'est wotking, le seul problème est que je mets l'icône gauche à dessin dans AppCompatEditText et il sera supprimé lorsque j'appellerai cette fonction, pouvez-vous s'il vous plaît me dire quel est le problème?
Arbaz.in
@ Arbaz.in C'est à cause de la méthode d'appel setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0). Vous pouvez passer l'identifiant de l'icône à gauche comme nouveau paramètre à cette fonction et le mettre dans l'appel.
Gulshan
@Gulshan j'ai fait la même chose encore supprimer ce drawable
Arbaz.in
20

La bibliothèque de support d'Android a une SearchViewclasse qui fait exactement cela. (Pas dérivé EditTextcependant, il faut donc utiliser un SearchView.OnQueryTextListenerau lieu d'un TextWatcher)

Vue de recherche sans texte (et texte de conseil "Rechercher")

entrez la description de l'image ici

Utilisez en XML comme ceci:

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

où x est:

entrez la description de l'image ici

Eamorr
la source
8
Nous devons encore attribuer un droit onClickListener? Une recherche rapide m'a donné ceci . Je suppose que la meilleure solution consiste à choisir celle de Framelayout. Merci quand même!
VenoM
6

Si vous ne souhaitez pas utiliser des vues personnalisées ou des dispositions spéciales, vous pouvez utiliser 9 patchs pour créer le bouton (X).

Exemple: http://postimg.org/image/tssjmt97p/ (je n'ai pas assez de points pour publier des images sur StackOverflow)

L'intersection des pixels noirs droit et inférieur représente la zone de contenu. Tout ce qui est en dehors de cette zone est du rembourrage. Donc, pour détecter que l'utilisateur a cliqué sur le x, vous pouvez définir un OnTouchListener comme ceci:

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

Selon vos besoins, cette solution peut mieux fonctionner dans certains cas. Je préfère garder mon xml moins compliqué. Cela est également utile si vous souhaitez avoir une icône à gauche, car vous pouvez simplement l'inclure dans le patch 9.

Andrei Tudor Diaconu
la source
4

J'ai fait la partie UI comme ci-dessous:

<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.pngentrez la description de l'image ici

Bouton croix / effacer masquer / afficher:

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

Gérer les éléments de recherche (c.-à-d. Lorsque l'utilisateur clique sur Rechercher à partir du clavier de touches programmables)

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

Bouton Clear / Cross

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

Utilisation

android:drawableRight="@android:drawable/ic_input_delete"
HimalayanCoder
la source
2

Voici la bibliothèque complète avec le widget: https://github.com/opprime/EditTextField

Pour l'utiliser, vous devez ajouter la dépendance:

compile 'com.optimus:editTextField:0.2.0'

Dans le fichier layout.xml, vous pouvez jouer avec les paramètres du widget:

xmlns:app="http://schemas.android.com/apk/res-auto"
  • app: clearButtonMode , peut avoir de telles valeurs: jamais toujours whileEditing saufEditing

  • app: clearButtonDrawable

Échantillon en action:

entrez la description de l'image ici

Kirill Vashilo
la source
2

Mettez juste une croix serrée comme drawableEnddans votre EditText:

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

et utilisez l'extension pour gérer les clics (ou utilisez OnTouchListenerdirectement sur votre 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
    }
}

utilisation de l'extension:

editText.onDrawableEndClick {
    // TODO clear action
    etSearch.setText("")
}
Francis
la source
1

Vous pouvez utiliser cet extrait de code avec la réponse Jaydip pour plusieurs boutons. il suffit de l'appeler après avoir obtenu une référence aux éléments ET et Button. J'ai utilisé le bouton vecotr, vous devez donc changer l'élément Button en 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
la source
0

Si vous êtes en disposition de cadre ou que vous pouvez créer une disposition de cadre, j'ai essayé une autre approche ....

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

Ceci est un texte d'édition où je mets une icône en croix comme un dessin à droite et qu'APRÈS, je mets un bouton transparent qui efface le texte.

Kleand Sherali
la source
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
la source