Як створити EditText за допомогою кнопки cross (x) в кінці?


198

Чи є якийсь віджет, на зразок EditTextякого міститься перехресна кнопка, чи є якесь властивість, за EditTextдопомогою якого воно створюється автоматично? Я хочу, щоб кнопкою хреста було видалено будь-який текст, написаний в EditText.


2
Здається, це не стандартний віджет для нього. Але ви знайдете кілька різних підходів у пошуку Google за "кнопкою очищення Android для редагування тексту Android". Тому я здогадуюсь, що "чіткі кнопки" - це те, як вони це називають. Крім того , побачити цей відповідь на відповідне питання: stackoverflow.com/questions/4175398/clear-edittext-on-click / ...
HostileFork говорить не довіряю SE

Ви можете завантажити джерело тут: github.com/GhOsTTT/editTextXbutton мають гарний день
Gökhan Musapaşaoğlu ヅ

Ще одне питання, яке по суті є дублікатом, це реалізація властивостей uitextfield в android
Алекс Кон

Відповіді:


166

Використовуйте такий макет:

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

Ви також можете використовувати ідентифікатор кнопки та виконувати будь-яку дію за методом onClickListener.


8
це неефективний спосіб зробити це. відповідь Янченка - правильний підхід до використання складених креслень.
numan salati

4
Якщо ви вибрали це рішення і помітили, що зображення занадто сильно розтягнуте, вам, ймовірно, слід використовувати ImageButton замість звичайної кнопки.
personne3000

3
Хоча це рішення "неефективне", воно набагато доступніше для незрячих користувачів. Використання малюнку змусить користувачів виконувати дуже складні операції з очищення тексту - те, що бачачи користувачі можуть швидко виконати за допомогою кнопки X.
Даніель Монтейро

2
У чому полягає неефективність у цьому?
Денні

121

Якщо вам трапляється використовувати DroidParts , я щойно додав ClearableEditText .

Ось як це виглядає з допомогою призначеного для користувача фону і ясному набір іконок для abs__ic_clear_holo_lightз ActionBarSherlock :

введіть тут опис зображення


11
Найкраще рішення, оскільки клас поширюється EditText. Thx @yanchenko
tbruyelle

2
@stephanek. Я зафіксував це у галузі розробки, буде частиною випуску 1.4.3.
Янченко

4
Дякую! Було б дуже здорово, хоча, якщо ви також можете включити ClearableAutoCompleteTextView в DroidParts. Для інших користувачів, які також намагаються це зробити: використовуйте бібліотеку DroidParts, скопіюйте код з ClearableEditText і просто розгорніть AutoCompleteTextView.
RobinDeCroon

2
Це бомба! Ви також можете використовувати його окремо, змінюючи залежність TextWatcherAdapter із звичайним TextWatcher.
Піментосо

1
@yanchenko Подивився на вашу реалізацію. Здається, що деяка помилка між прийнятою сенсорною областю є досить невеликою і має текст редагування, більший за висоту за замовчуванням, приймаючи події дотику по всій осі y в межах редагування тексту. Ваша реалізація була першою, а моя останньою. За подібних обставин ви б рекомендували робити те саме? тобто перейдіть до меншої скриньки для потрапляння, яку можна пропустити, або мати більшу скриньку, де з розширюваним чи більшим текстом редагування натискання можуть бути далеко поза межами малюваного.
Джек.Рамсден

63

Рішення 2020 року через Material Design Components для Android:

Додайте матеріальні компоненти до налаштування gradle:

Шукайте останню версію тут: https://maven.google.com/

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

або якщо у вас не з’явилося оновлення на використання AndroidX libs, ви можете додати це таким чином:

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

Тоді

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

Зверніть увагу на: app: endIconMode = "clear_text"

Як обговорювалося тут Документи дизайну матеріалів


10
Це має бути нова прийнята відповідь. У моєму випадку я не зміг реалізувати без оновлення до бібліотек AndroidX.
Бен

@Ben (великі пальці вгору)
кевороїд

Не забудьте прочитати документацію, оскільки ще не всі атрибути xml підтримуються. Можливо, вам доведеться переглядати джерело або вводити повідомлення, оскільки вони інколи є точними деталями реалізації. У мене був такий тип випуску для користувацького endIcon. Повідомлення про фіксацію виявило, що атрибут xml ще не підтримував його. Доведеться використовувати інший підхід, поки впровадження не закінчиться
М. Сміт

Найкраща відповідь у 2020 році.
Сем Чен

чи працює програма: endIconMode = "clear_text" <androidx.appcompat.widget.AppCompatEditText/>? Ви можете мені допомогти в тому ж самому
Arbaz.in

32

Це рішення котліна. Помістіть цей помічний метод у якийсь файл 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
    })
}

А потім використовуйте його як наступне в onCreateметоді, і вам слід добре пройти-

yourEditText.setupClearButtonWithAction()

До речі, спочатку потрібно додати R.drawable.ic_clearабо очистити піктограму. Це з google- https://material.io/tools/icons/?icon=clear&style=baseline


Якщо ви вставите this.clearFocus()перед поверненням справжнього твердження, ви можете слухати цю подію на абоненті EditText зі onFocusChangeслухачем
Joost Schepel

Чудово, що це wotking, єдине питання, що я встановив значок, що виводиться ліворуч у AppCompatEditText, і він видалиться, коли я зателефоную на цю функцію, чи можете ви скажіть, у чому проблема?
Arbaz.in

@ Arbaz.in Це через метод виклику setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0). Ви можете передати лівий значок, що виводиться, як новий параметр цієї функції та ввести його у виклик.
Гульшан

@Gulshan Я зробив те ж все-таки видалити те, що
малюється

20

Ліберал підтримки Android має SearchViewклас, який робить саме це. (Не випливає з EditTextоднак, тому доведеться використовувати SearchView.OnQueryTextListenerзамість а TextWatcher)

Перегляд пошуку без тексту (та тексту підказки "Пошук")

введіть тут опис зображення

Використовуйте XML так:

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

де x є:

введіть тут опис зображення


8
Все ж нам потрібно призначити onClickListener правильно? Швидкий пошук дав мені це . Здогадайтесь, краще рішення - перейти з Framelayout. Дякую, хоча!
VenoM


6

Якщо ви не хочете використовувати власні представлення даних або спеціальні макети, ви можете використовувати 9-патч для створення кнопки (X).

Приклад: http://postimg.org/image/tssjmt97p/ (у мене недостатньо балів для розміщення зображень на StackOverflow)

Перетин правого та нижнього чорних пікселів представляє область вмісту. Все, що знаходиться поза цією зоною, - це підкладка. Отже, щоб виявити, що користувач натиснув на x, ви можете встановити OnTouchListener так:

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

Відповідно до ваших потреб, у деяких випадках це рішення може працювати краще. Я вважаю за краще зберігати свій xml менш складним. Це також допомагає, якщо ви хочете мати піктограму зліва, оскільки ви можете просто включити її в 9 патч.


4

Я зробив частину інтерфейсу, як показано нижче:

<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.pngвведіть тут опис зображення

Перехрестити / очистити кнопку приховати / показати

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

Обробляти матеріали пошуку (наприклад, коли користувач натискає пошук з панелі клавіш)

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

Кнопка «Очистити / перехрестити»

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


2

Ось повна бібліотека з віджетом: https://github.com/opprime/EditTextField

Для його використання слід додати залежність:

compile 'com.optimus:editTextField:0.2.0'

У файлі layout.xml ви можете грати з налаштуваннями віджета:

xmlns:app="http://schemas.android.com/apk/res-auto"
  • додаток: clearButtonMode , може мати такі значення: ніколи не завжди під час редагування, якщо редагування

  • додаток: clearButtonDrawable

Зразок дії:

введіть тут опис зображення


2

Просто поставте близький хрест, як drawableEndу вашому EditText:

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

і використовувати розширення для обробки клацання (або використання OnTouchListenerбезпосередньо на вашому 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
    }
}

використання розширення:

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

1

Ви можете використовувати цей фрагмент з відповіддю Джейдіпа для більш ніж однієї кнопки. просто зателефонуйте до нього після отримання посилання на елементи ЕТ та Кнопки. Я використав кнопку vecotr, тому вам доведеться змінити елемент Button на 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

Якщо ви знаходитесь в макеті кадру або ви можете створити макет кадру, я спробував інший підхід ....

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

Це текст для редагування, куди я кладу значок хреста як право малювання, а потім НАГОРОДИМ я кладу прозору кнопку, яка очищає текст.


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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.