Come creare EditText con il tasto croce (x) alla fine?


198

Esiste un widget come quello EditTextche contiene un pulsante a croce o esiste una proprietà per la EditTextquale viene creato automaticamente? Voglio che il pulsante a croce elimini qualunque testo scritto EditText.


2
Non sembra essere alcun widget standard per esso. Ma trovi alcuni approcci diversi con una ricerca su Google per "pulsante cancella edittext x". Quindi immagino che "pulsanti chiari" sia come lo chiamano. Inoltre, vedere questa risposta ad una domanda correlata: stackoverflow.com/questions/4175398/clear-edittext-on-click/...
HostileFork dice fiducia Dont SE

Puoi scaricare la fonte qui: github.com/GhOsTTT/editTextXbutton buona giornata
Gökhan Musapaşaoğlu ヅ

un'altra domanda che è essenzialmente un duplicato è implementare le proprietà uitextfield in Android
Alex Cohn,

Risposte:


166

Usa il seguente 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>

Puoi anche usare l'ID del pulsante ed eseguire qualsiasi azione tu voglia sul suo metodo onClickListener.


8
questo è un modo inefficiente per farlo. La risposta di yanchenko è il giusto approccio all'utilizzo di drawable composti.
numan salati

4
Se ti capita di scegliere questa soluzione e noti che l'immagine è troppo allungata, probabilmente dovresti usare un ImageButton invece di un normale Button.
personne3000,

3
Sebbene questa soluzione sia "inefficiente", è molto più accessibile per gli utenti non vedenti. L'uso di un disegno costringerà i tuoi utenti a eseguire operazioni molto complicate per cancellare il testo, cosa che vedere gli utenti può fare rapidamente con il pulsante X.
Daniel Monteiro,

2
Qual è l'inefficienza di questo?
Denny,

121

Se ti capita di usare DroidParts , ho appena aggiunto ClearableEditText .

Ecco come appare con uno sfondo personalizzato e un'icona chiara impostata su abs__ic_clear_holo_lightda ActionBarSherlock :

inserisci qui la descrizione dell'immagine


11
La migliore soluzione perché la classe si estende EditText. Thx @yanchenko
tbruyelle

2
@stephanek. Ho risolto questo problema nel ramo di sviluppo, farà parte della versione 1.4.3.
yanchenko,

4
Grazie! Sarebbe davvero bello se si potesse includere anche un ClearableAutoCompleteTextView in DroidParts. Per gli altri utenti che provano anche a fare questo: usa la libreria DroidParts, copia il codice da ClearableEditText ed estendi AutoCompleteTextView.
RobinDeCroon,

2
Questa è una bomba! Puoi anche usarlo autonomamente modificando la dipendenza TextWatcherAdapter con un normale TextWatcher.
Pimentoso,

1
@yanchenko Ho dato un'occhiata alla tua implementazione. Sembra che ci sia un piccolo compromesso tra l'area di tocco accettata essendo piuttosto piccola e avendo un testo di modifica con un'altezza maggiore di quella predefinita che accetta eventi di tocco lungo l'asse y all'interno del testo di modifica. La tua implementazione è stata la prima e la mia la seconda. In circostanze simili consiglieresti di fare lo stesso? vale a dire scegliere una hit box più piccola che potrebbe essere premuta in modo errato o avere una hit box più grande, dove, con un testo di modifica in espansione o più grande, le macchine da stampa potrebbero essere ben al di fuori dei limiti del disegno.
Jack

64

Soluzione 2020 tramite Material Design Components per Android:

Aggiungi componenti materiali alla tua configurazione gradle:

Cerca l'ultima versione da qui: https://maven.google.com/

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

o se non hai aggiornato all'utilizzo delle librerie AndroidX, puoi aggiungerlo in questo modo:

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

Poi

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

Prestare attenzione a: app: endIconMode = "clear_text"

Come discusso qui Documenti di progettazione dei materiali


10
Questa dovrebbe essere la nuova risposta accettata. Nel mio caso, non sono stato in grado di implementare senza l'aggiornamento alle librerie AndroidX.
Ben

@Ben (pollice alzato)
kevoroid

Leggere attentamente la documentazione poiché non tutti gli attributi xml sono ancora supportati. Potrebbe essere necessario esaminare la fonte o eseguire il commit dei messaggi, in quanto a volte si trovano esattamente i dettagli di implementazione. Ho avuto questo tipo di problema per un endIcon personalizzato. Un messaggio di commit ha rivelato che l'attributo xml non ha ancora implementato l'implementazione. Dovrà utilizzare un approccio diverso fino al termine dell'implementazione
M. Smith,

Migliore risposta nel 2020.
Sam Chen,

app: endIconMode = "clear_text" è workign con <androidx.appcompat.widget.AppCompatEditText/>? potete per favore aiutarmi nello stesso
Arbaz. in

32

Questa è una soluzione kotlin. Inserisci questo metodo di supporto in alcuni file di 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
    })
}

E poi usalo come segue nel onCreatemetodo e dovresti essere bravo ad andare-

yourEditText.setupClearButtonWithAction()

A proposito, devi aggiungere R.drawable.ic_clearo l'icona chiara all'inizio. Questo è di google- https://material.io/tools/icons/?icon=clear&style=baseline


Se si inserisce this.clearFocus()prima dell'istruzione return true, è possibile ascoltare questo evento sul chiamante EditText con l' onFocusChangeascoltatore
Joost Schepel,

Grande è wotking, l'unico problema è che ho impostato l'icona sinistra disegnabile in AppCompatEditText e rimuoverò quando chiamo questa funzione, per favore, puoi dirmi qual è il problema?
Arbaz.in

@ Arbaz.in È a causa del metodo di chiamata setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0). È possibile passare l'ID dell'icona di disegno a sinistra come nuovo parametro a questa funzione e inserirlo nella chiamata.
Gulshan,

@Gulshan ho fatto lo stesso rimuovendo ancora quel drawable
Arbaz.in

20

Il libarario di supporto di Android ha una SearchViewclasse che fa esattamente questo. (Non derivato da EditTextperò, quindi devi usare un SearchView.OnQueryTextListenerinvece di a TextWatcher)

Ricerca vista senza testo (e suggerimento "Cerca")

inserisci qui la descrizione dell'immagine

Utilizzare in XML in questo modo:

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

16
Drawable x = getResources().getDrawable(R.drawable.x);
x.setBounds(0, 0, x.getIntrinsicWidth(), x.getIntrinsicHeight());
mEditText.setCompoundDrawables(null, null, x, null);

dove, x è:

inserisci qui la descrizione dell'immagine


8
Dobbiamo ancora assegnare un onClickListener giusto? Una rapida ricerca mi ha dato questo . Immagino che la soluzione migliore sia quella di Framelayout. Grazie comunque!
VenoM,


6

Se non si desidera utilizzare viste personalizzate o layout speciali, è possibile utilizzare 9-patch per creare il pulsante (X).

Esempio: http://postimg.org/image/tssjmt97p/ (Non ho abbastanza punti per pubblicare immagini su StackOverflow)

L'intersezione dei pixel neri destro e inferiore rappresenta l'area del contenuto. Qualunque cosa al di fuori di quell'area è imbottitura. Quindi, per rilevare che l'utente ha fatto clic sulla x è possibile impostare un OnTouchListener in questo modo:

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

In base alle tue esigenze, in alcuni casi questa soluzione può funzionare meglio. Preferisco mantenere il mio xml meno complicato. Questo aiuta anche se vuoi avere un'icona a sinistra, in quanto puoi semplicemente includerla nella patch 9.


4

Ho fatto la parte dell'interfaccia utente come di seguito:

<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.pnginserisci qui la descrizione dell'immagine

Pulsante Cross / Clear nascondi / mostra:

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

Gestire elementi di ricerca (ad es. Quando l'utente fa clic sulla ricerca dalla tastiera virtuale)

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

Pulsante Cancella / Croce

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


2

Ecco la libreria completa con il widget: https://github.com/opprime/EditTextField

Per usarlo è necessario aggiungere la dipendenza:

compile 'com.optimus:editTextField:0.2.0'

Nel file layout.xml puoi giocare con le impostazioni del widget:

xmlns:app="http://schemas.android.com/apk/res-auto"
  • app: clearButtonMode , può avere tali valori: mai sempre mentre Modifica a meno che Modifica

  • app: clearButtonDrawable

Esempio in azione:

inserisci qui la descrizione dell'immagine


2

Basta mettere una croce stretta come drawableEndnel tuo EditText:

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

e usa l'estensione per gestire il clic (o usa OnTouchListenerdirettamente sul tuo 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
    }
}

utilizzo estensione:

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

1

Puoi utilizzare questo frammento con la risposta di Jaydip per più di un pulsante. basta chiamarlo dopo aver ottenuto un riferimento a ET e Button Elements. Ho usato il pulsante vecotr quindi devi cambiare l'elemento Button in 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);
                }
            }
        });
    }

0

Se sei nel layout del frame o puoi creare un layout del frame, ho provato un altro approccio ....

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

Questo è un testo di modifica in cui ho messo un'icona a forma di croce come un disegno a destra e di UPON ho messo un pulsante trasparente che cancella il testo.


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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.