Jak utworzyć EditText za pomocą przycisku krzyżyka (x) na jego końcu?


198

Czy jest jakikolwiek widżet, EditTextktóry zawiera przycisk krzyżyka, czy jest jakaś właściwość, dla EditTextktórej jest tworzony automatycznie? Chcę, aby przycisk krzyżyka usunął tekst napisany w EditText.


2
Nie wydaje się być dla niego żadnym standardowym widgetem. Ale możesz znaleźć kilka różnych podejść, wyszukując w Google „android edittext wyczyść przycisk x”. Sądzę więc, że nazywają to „czystymi przyciskami”. Zobacz także odpowiedź na powiązane pytanie: stackoverflow.com/questions/4175398/clear-edittext-on-click/…
HostileFork mówi, że nie ufaj

Możesz pobrać źródło tutaj: github.com/GhOsTTT/editTextXbutton miłego dnia
Gökhan Musapaşaoğlu ヅ

innym pytaniem, które jest w zasadzie duplikatem, jest implementacja właściwości uitextfield w Androidzie
Alex Cohn

Odpowiedzi:


166

Użyj następującego układu:

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

Możesz także użyć identyfikatora przycisku i wykonać dowolną akcję na jego metodzie onClickListener.


8
jest to nieefektywny sposób na zrobienie tego. odpowiedź Janczenki to właściwe podejście do używania złożonych drawables.
numan salati 10.04.13

4
Jeśli zdarzy ci się wybrać to rozwiązanie i zauważysz, że obraz jest zbyt mocno rozciągnięty, prawdopodobnie powinieneś użyć ImageButton zamiast zwykłego przycisku.
personne3000,

3
Chociaż to rozwiązanie jest „nieefektywne”, jest o wiele bardziej dostępne dla niewidomych użytkowników. Korzystanie z drawable zmusi użytkowników do wykonywania bardzo skomplikowanych operacji czyszczenia tekstu - co widzą użytkownicy mogą zrobić szybko za pomocą przycisku X.
Daniel Monteiro,

2
Jaka jest w tym nieefektywność?
Denny

121

Jeśli zdarzy ci się używać DroidParts , właśnie dodałem ClearableEditText .

Oto jak to wygląda z niestandardowego tła i jasny zestaw ikon do abs__ic_clear_holo_lightod ActionBarSherlock :

wprowadź opis zdjęcia tutaj


11
Najlepsze rozwiązanie, ponieważ klasa się powiększa EditText. Dzięki @yanchenko
tbruyelle

2
@stephanek. Naprawiłem to w gałęzi deweloperskiej, będzie częścią wydania 1.4.3.
yanchenko

4
Dzięki! Byłoby naprawdę fajnie, gdybyś mógł również włączyć ClearableAutoCompleteTextView w DroidParts. Dla innych użytkowników, którzy również próbują to zrobić: użyj biblioteki DroidParts, skopiuj kod z ClearableEditText i po prostu rozszerz AutoCompleteTextView.
RobinDeCroon

2
To jest bomba! Możesz go również używać samodzielnie, zmieniając zależność TextWatcherAdapter za pomocą zwykłego TextWatchera.
Pimentoso,

1
@yanchenko Obejrzyj swoją implementację. Wydaje się, że istnieje pewien kompromis między akceptowanym obszarem dotykowym, który jest raczej mały i ma edytowany tekst o większej niż domyślna wysokości, akceptujący zdarzenia dotykowe na całej osi y w obrębie edytowanego tekstu. Twoje wdrożenie było pierwsze, a moje drugie. Czy w podobnych okolicznościach poleciłbyś zrobić to samo? tzn. wybierz mniejsze pole trafienia, które można pominąć lub mieć większe pole trafienia, w którym przy rozszerzającym się lub większym tekście edycji prasy mogą znajdować się poza granicami obszaru rysowalnego.
Jack.Ramsden

63

Rozwiązanie 2020 za pośrednictwem Material Design Components dla Androida:

Dodaj komponenty materiałowe do konfiguracji stopni:

Poszukaj najnowszej wersji tutaj: https://maven.google.com/

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

lub jeśli nie zaktualizowałeś się do korzystania z bibliotek AndroidX, możesz dodać to w ten sposób:

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

Następnie

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

Zwróć uwagę na: app: endIconMode = "clear_text"

Jak omówiono tutaj Dokumenty dotyczące projektowania materiałów


10
To powinna być nowa zaakceptowana odpowiedź. W moim przypadku nie byłem w stanie zaimplementować bez aktualizacji bibliotek AndroidX.
Ben

@Ben (kciuk w górę)
kevoroid

Zapoznaj się z dokumentacją, ponieważ nie wszystkie atrybuty xml są jeszcze obsługiwane. Konieczne może być przejrzenie wiadomości źródłowej lub zatwierdzenie wiadomości, ponieważ czasami są tam dokładne szczegóły implementacji. Miałem tego typu problem z niestandardowym interfejsem użytkownika. Komunikat zatwierdzenia ujawnił, że atrybut xml nie ma jeszcze implementacji, która go wspiera. Będą musieli zastosować inne podejście, dopóki wdrożenie nie zostanie zakończone
M. Smith

Najlepsza odpowiedź w 2020 r.
Sam Chen,

czy app: endIconMode = "clear_text" działa z <androidx.appcompat.widget.AppCompatEditText/>? czy możesz mi pomóc w tym samym
Arbaz.in

32

To rozwiązanie kotlin. Umieść tę metodę pomocniczą w pliku 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
    })
}

A następnie użyj go w następujący sposób w onCreatemetodzie i powinieneś być dobry-

yourEditText.setupClearButtonWithAction()

BTW, musisz najpierw dodać R.drawable.ic_clearlub wyczyścić ikonę. Ten jest z google- https://material.io/tools/icons/?icon=clear&style=baseline


Jeśli wstawisz this.clearFocus()przed zwracaną instrukcją true, możesz słuchać tego zdarzenia w programie wywołującym onFocusChange
EditText

Świetnie, pracuję, jedynym problemem jest ustawienie rysowanej lewej ikony w AppCompatEditText i zostanie usunięta, gdy wywołam tę funkcję. Czy możesz mi powiedzieć, jaki jest problem?
Arbaz.in

@ Arbaz.in Jest to spowodowane wywołaniem metody setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0). Możesz przekazać lewy id ikony do rysowania jako nowy parametr do tej funkcji i umieścić ją w wywołaniu.
Gulshan

@Gulshan zrobiłem to samo nadal usuwam ten drawable
Arbaz.in

20

Wsparcie dla Androida ma SearchViewklasę, która właśnie to robi. (Nie jest jednak pozbawiony EditText, więc należy użyć SearchView.OnQueryTextListenerzamiast a TextWatcher)

Wyszukaj widok bez tekstu (i podpowiedź „Szukaj”)

wprowadź opis zdjęcia tutaj

Użyj w XML tak:

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

gdzie x jest:

wprowadź opis zdjęcia tutaj


8
Nadal musimy przypisać właściwość onClickListener? Szybkie wyszukiwanie dało mi to . Chyba lepszym rozwiązaniem jest pójście z Framelayout. W każdym razie dzięki!
VenoM


6

Jeśli nie chcesz używać niestandardowych widoków lub układów specjalnych, możesz użyć 9-łatek, aby utworzyć przycisk (X).

Przykład: http://postimg.org/image/tssjmt97p/ (Nie mam wystarczającej liczby punktów, aby publikować obrazy na StackOverflow)

Przecięcie prawego i dolnego czarnego piksela reprezentuje obszar zawartości. Wszystko poza tym obszarem jest wyściełane. Aby wykryć, że użytkownik kliknął x, możesz ustawić OnTouchListener w następujący sposób:

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

W zależności od potrzeb rozwiązanie to może w niektórych przypadkach działać lepiej. Wolę, aby mój xml był mniej skomplikowany. Pomaga to również, jeśli chcesz mieć ikonę po lewej stronie, ponieważ możesz po prostu dołączyć ją do łatki 9.


4

Zrobiłem część interfejsu użytkownika jak poniżej:

<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.pngwprowadź opis zdjęcia tutaj

Przycisk krzyż / Wyczyść ukryj / pokaż:

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

Obsługa wyszukiwania (np. Gdy użytkownik kliknie wyszukiwanie z tablicy klawiszy programowych)

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

Przycisk Clear / Cross

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


2

Oto pełna biblioteka z widżetem: https://github.com/opprime/EditTextField

Aby z niego skorzystać, należy dodać zależność:

compile 'com.optimus:editTextField:0.2.0'

W pliku layout.xml można odtwarzać z ustawieniami widgetu:

xmlns:app="http://schemas.android.com/apk/res-auto"
  • app: clearButtonMode can może mieć takie wartości: nigdy nie należy podczas edycji, chyba że edycja

  • aplikacja: clearButtonDrawable

Próbka w akcji:

wprowadź opis zdjęcia tutaj


2

Po prostu postaw krzyżyk jak drawableEndw swoim EditText:

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

i użyj rozszerzenia do obsługi kliknięcia (lub użyj OnTouchListenerbezpośrednio na swoim 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
    }
}

użycie rozszerzenia:

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

1

Możesz użyć tego fragmentu kodu z odpowiedzią Jaydip dla więcej niż jednego przycisku. po prostu zadzwoń po uzyskaniu odniesienia do ET i elementów przycisku. Użyłem przycisku vecotr, więc musisz zmienić element Button na 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

Jeśli jesteś w układzie ramek lub możesz utworzyć układ ramek, wypróbowałem inne podejście ....

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

To jest tekst edycyjny, w którym po prawej stronie rysuję ikonę krzyżyka, a następnie W GÓRĘ umieszczam przezroczysty przycisk, który usuwa tekst.


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;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.