Como criar o EditText com o botão de cruz (x) no final?


198

Existe algum widget como o EditTextque contém um botão cruzado ou alguma propriedade para a EditTextqual ele é criado automaticamente? Quero que o botão de cruz apague qualquer texto escrito EditText.


2
Não parece ser um widget padrão para ele. Mas você encontra algumas abordagens diferentes com uma pesquisa no Google por "android edittext clear button x". Então eu acho que "botões claros" é o que eles chamam. Além disso, consulte esta resposta a uma pergunta relacionada: stackoverflow.com/questions/4175398/clear-edittext-on-click/…
HostileFork diz que não confia em

Você pode fazer o download da fonte aqui: github.com/GhOsTTT/editTextXbutton tenha um bom dia
Gökhan Musapaşaoğlu ヅ

outra questão que é essencialmente um duplicado é implementar propriedades UITextField em android
Alex Cohn

Respostas:


166

Use o seguinte 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>

Você também pode usar a identificação do botão e executar qualquer ação que desejar no método onClickListener.


8
essa é uma maneira ineficiente de fazê-lo. A resposta de yanchenko é a abordagem correta do uso de drawables compostos.
Numan salati

4
Se você escolher esta solução e perceber que a imagem está muito esticada, provavelmente use um ImageButton em vez de um botão comum.
personne3000

3
Embora essa solução seja "ineficiente", é muito mais acessível para usuários cegos. O uso de um drawable forçará seus usuários a executar operações muito complicadas para limpar o texto - algo que os usuários podem fazer rapidamente com o botão X.
Daniel Monteiro

2
Qual é a ineficiência nisso?
Denny

121

Se você usa o DroidParts , acabei de adicionar o ClearableEditText .

Aqui está o que parece com um fundo personalizado e claro conjunto de ícones a abs__ic_clear_holo_lightpartir ActionBarSherlock :

insira a descrição da imagem aqui


11
Melhor solução porque a classe se estende EditText. Thx @yanchenko
tbruyelle

2
@stephanek. Corrigi isso no ramo de desenvolvimento, fará parte da versão 1.4.3.
Yanchenko

4
Obrigado! Seria muito legal, se você também pudesse incluir um ClearableAutoCompleteTextView no DroidParts. Para outros usuários que também tentam fazer isso: use a biblioteca DroidParts, copie o código de ClearableEditText e apenas estenda o AutoCompleteTextView.
224146 RobinDeCroon

2
Isso é bomba! Você também pode usá-lo de maneira independente, alterando a dependência do TextWatcherAdapter com um TextWatcher normal.
Pimentoso

1
@yanchenko Deu uma olhada na sua implementação. Parece que existe uma pequena diferença entre a área de toque aceita ser bastante pequena e ter um texto de edição com uma altura maior que a padrão, aceitando eventos de toque ao longo do eixo y no texto de edição. Sua implementação foi a primeira e a minha a segunda. Em circunstâncias semelhantes, você recomendaria fazer o mesmo? ou seja, escolha uma caixa de acertos menor que possa ser pressionada incorretamente ou que tenha uma caixa de acertos maior, onde, com um texto de edição em expansão ou maior, as impressoras podem estar bem fora dos limites do drawable.
precisa saber é o seguinte

64

Solução 2020 via Material Design Components para Android:

Adicione Componentes do material à sua configuração de gradiente:

Procure a versão mais recente aqui: https://maven.google.com/

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

ou se você não tiver atualizado o uso das bibliotecas do AndroidX, poderá adicioná-lo desta maneira:

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

Então

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

Preste atenção em: app: endIconMode = "clear_text"

Conforme discutido aqui , documentos de design de materiais


10
Essa deve ser a nova resposta aceita. No meu caso, não consegui implementar sem atualizar para as bibliotecas AndroidX.
Ben

@Ben (thumbs up)
kevoroid

Leia a documentação, pois nem todos os atributos xml ainda são suportados. Pode ser necessário procurar na fonte ou confirmar as mensagens, pois essas são algumas vezes onde estão os detalhes exatos da implementação. Eu tive esse tipo de problema para um endIcon personalizado. Uma mensagem de confirmação revelou que o atributo xml ainda não tinha implementação de backup. Terá que usar uma abordagem diferente até que a implementação seja concluída
M. Smith

Melhor resposta em 2020.
Sam Chen

app: endIconMode = "clear_text" está funcionando <androidx.appcompat.widget.AppCompatEditText/>? você pode por favor me ajudar na mesma
Arbaz.in

32

Esta é uma solução kotlin. Coloque esse método auxiliar em algum arquivo 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, em seguida, use-o da seguinte forma no onCreatemétodo e você deve ser bom em

yourEditText.setupClearButtonWithAction()

BTW, você deve adicionar R.drawable.ic_clearou o ícone claro primeiro. Este é do google- https://material.io/tools/icons/?icon=clear&style=baseline


Se você inserir this.clearFocus()antes da declaração true de retorno, poderá ouvir esse evento no chamador onFocusChange
EditText

Ótimo, está funcionando, o único problema é que eu defina o ícone esquerdo desenhável no AppCompatEditText e ele será removido quando eu chamar essa função. Você pode me dizer qual é o problema?
Arbaz.in 21/04

@ Arbaz.in É por causa do método de chamada setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0). Você pode passar o ID do ícone da gaveta esquerdo como um novo parâmetro para esta função e colocá-lo na chamada.
Gulshan

@Gulshan eu fiz o mesmo ainda remover esse drawable
Arbaz.in

20

A biblioteca de suporte do Android tem uma SearchViewclasse que faz exatamente isso. (Não é derivado EditText, porém, é necessário usar um em SearchView.OnQueryTextListenervez de a TextWatcher)

Visualização de pesquisa sem texto (e texto de dica "Pesquisar")

insira a descrição da imagem aqui

Use em XML assim:

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

onde x é:

insira a descrição da imagem aqui


8
Ainda precisamos atribuir um onClickListener, certo? Uma pesquisa rápida me deu isso . Acho que a melhor solução é ir com o Framelayout. Obrigado embora!
VenoM 22/03


6

Se você não quiser usar visualizações personalizadas ou layouts especiais, use o patch 9 para criar o botão (X).

Exemplo: http://postimg.org/image/tssjmt97p/ (não tenho pontos suficientes para postar imagens no StackOverflow)

A interseção dos pixels pretos direito e inferior representa a área de conteúdo. Qualquer coisa fora dessa área é preenchida. Portanto, para detectar que o usuário clicou no x, você pode definir um OnTouchListener da seguinte forma:

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

De acordo com suas necessidades, esta solução pode funcionar melhor em alguns casos. Eu prefiro manter meu xml menos complicado. Isso também ajuda se você quiser ter um ícone à esquerda, pois você pode simplesmente incluí-lo no patch 9.


4

Eu fiz a parte da interface do usuário como abaixo:

<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.pnginsira a descrição da imagem aqui

Ocultar / mostrar botão cruzar / limpar:

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

Manipular itens de pesquisa (ou seja, quando o usuário clica em pesquisa no teclado virtual)

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ão Limpar / Cruzar

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


2

Aqui está a biblioteca completa com o widget: https://github.com/opprime/EditTextField

Para usá-lo, você deve adicionar a dependência:

compile 'com.optimus:editTextField:0.2.0'

No arquivo layout.xml, você pode jogar com as configurações do widget:

xmlns:app="http://schemas.android.com/apk/res-auto"
  • app: clearButtonMode , can tem esses valores: nunca sempre whileEditing, a menos queEditing

  • app: clearButtonDrawable

Amostra em ação:

insira a descrição da imagem aqui


2

Basta colocar uma cruz fechada como drawableEndno seu EditText:

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

e use a extensão para manipular o clique (ou use OnTouchListenerdiretamente no seu 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 extensão:

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

1

Você pode usar esse trecho com a resposta Jaydip para mais de um botão. basta chamá-lo depois de obter uma referência aos elementos ET e Button. Eu usei o botão vecotr, então você precisa alterar o elemento Button para 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 você estiver no layout do quadro ou puder criar um layout do quadro, tentei outra abordagem ....

<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 é um texto de edição onde eu coloco um ícone de cruz como um drawable à direita e, em seguida, coloco um botão transparente que limpa o texto.


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;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.