Làm cách nào để tạo EditText bằng nút chéo (x) ở cuối của nó?


198

Có tiện ích EditTextnào chứa nút chéo hoặc có thuộc tính nào EditTextđược tạo tự động không? Tôi muốn nút chéo để xóa bất cứ văn bản nào được viết EditText.


2
Không có vẻ là bất kỳ widget tiêu chuẩn cho nó. Nhưng bạn tìm thấy một vài cách tiếp cận khác nhau với một tìm kiếm Google cho "android edittext Clear button x". Vì vậy, tôi đoán "các nút rõ ràng" là những gì họ gọi nó. Ngoài ra, hãy xem câu trả lời này cho một câu hỏi liên quan: stackoverflow.com/questions/4175398/clear-edittext-on-click/
mẹo

Bạn có thể tải nguồn tại đây: github.com/GhOsTTT/editTextXbutton chúc một ngày tốt lành
Gökhan Musapaşaoğlu

một câu hỏi khác về cơ bản là trùng lặp là triển khai các thuộc tính uitextfield trong Android
Alex Cohn

Câu trả lời:


166

Sử dụng bố cục sau:

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

Bạn cũng có thể sử dụng id của nút và thực hiện bất kỳ hành động nào bạn muốn trên phương thức onClickListener của nó.


8
đây là một cách làm không hiệu quả Câu trả lời của yanchenko là cách tiếp cận đúng đắn của việc sử dụng hợp chất rút thăm.
numan salati

4
Nếu bạn tình cờ chọn giải pháp này và nhận thấy rằng hình ảnh bị kéo dài quá nhiều, có lẽ bạn nên sử dụng ImageButton thay vì Nút thông thường.
personne3000

3
Mặc dù giải pháp này là "không hiệu quả", nhưng nó dễ tiếp cận hơn đối với người dùng mù. Sử dụng drawable sẽ buộc người dùng của bạn thực hiện các thao tác rất phức tạp để xóa văn bản - điều mà người dùng thấy có thể thực hiện nhanh chóng bằng nút X.
Daniel Monteiro

2
Điều gì không hiệu quả về điều này?
Denny

121

Nếu bạn tình cờ sử dụng DroidParts , tôi vừa thêm CleaabilitiesEditText .

Đây là giao diện của nền tùy chỉnh & biểu tượng rõ ràng được đặt abs__ic_clear_holo_lighttừ ActionBarSherlock :

nhập mô tả hình ảnh ở đây


11
Giải pháp tốt nhất vì lớp học mở rộng EditText. Thx @yanchenko
tbruyelle

2
@stephanek. Tôi đã sửa lỗi này trong nhánh phát triển, sẽ là một phần của phiên bản 1.4.3.
yanchenko

4
Cảm ơn! Nó sẽ thực sự tuyệt vời mặc dù nếu bạn cũng có thể bao gồm CleaabilitiesAutoCompleteTextView trong DroidParts. Đối với những người dùng khác cũng cố gắng thực hiện việc này: sử dụng thư viện DroidParts, sao chép mã từ CleaabilitiesEditText và chỉ cần mở rộng AutoCompleteTextView.
RobinDeCroon

2
Đây là bom! Bạn cũng có thể sử dụng nó độc lập thay đổi phụ thuộc TextWatcherAd CHƯƠNG với TextWatcher bình thường.
Pimentoso

1
@yanchenko Có một cái nhìn về việc thực hiện của bạn. Có vẻ như có một chút đánh đổi giữa khu vực cảm ứng được chấp nhận là khá nhỏ và có một văn bản chỉnh sửa có chiều cao mặc định hơn chấp nhận các sự kiện chạm dọc theo trục y trong văn bản chỉnh sửa. Việc thực hiện của bạn là trước đây và của tôi sau này. Trong trường hợp tương tự, bạn sẽ khuyên bạn nên làm như vậy? tức là sử dụng hộp nhấn nhỏ hơn có thể bị bấm sai hoặc có hộp nhấn lớn hơn, trong đó, với văn bản chỉnh sửa mở rộng hoặc lớn hơn, các lần nhấn có thể nằm ngoài giới hạn của hình vẽ.
Jack.Ramsden

64

Giải pháp 2020 thông qua các thành phần thiết kế vật liệu cho Android:

Thêm thành phần vật liệu vào thiết lập lớp của bạn:

Tìm phiên bản mới nhất từ ​​đây: https://maven.google.com/

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

hoặc nếu bạn chưa cập nhật để sử dụng lib AndroidX, bạn có thể thêm nó theo cách này:

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

Sau đó

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

Hãy chú ý đến: app: endIconMode = "Clear lòng"

Như đã thảo luận ở đây Tài liệu thiết kế vật liệu


10
Đây phải là câu trả lời mới được chấp nhận. Trong trường hợp của tôi, tôi không thể thực hiện mà không cập nhật lên thư viện AndroidX.
Ben

@Ben (giơ ngón tay cái lên)
kevoroid

Hãy chắc chắn đọc qua tài liệu vì không phải tất cả các thuộc tính xml đều được hỗ trợ. Bạn có thể phải xem qua các nguồn hoặc cam kết thông báo vì đôi khi chúng là chi tiết triển khai chính xác. Tôi đã có loại vấn đề này cho một endIcon tùy chỉnh. Một thông báo cam kết tiết lộ rằng thuộc tính xml chưa thực hiện sao lưu nó. Sẽ phải sử dụng một cách tiếp cận khác cho đến khi việc thực hiện kết thúc
M. Smith

Câu trả lời hay nhất năm 2020.
Sam Chen

ứng dụng: endIconMode = "Clear lòng" có phù hợp với <androidx.appcompat.widget.AppCompatEditText/>không? bạn có thể vui lòng giúp tôi không
Arbaz.in

32

Đây là một giải pháp kotlin. Đặt phương thức trợ giúp này trong một số tệp 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
    })
}

Và sau đó sử dụng nó như sau trong onCreatephương pháp và bạn sẽ thấy tốt

yourEditText.setupClearButtonWithAction()

BTW, bạn phải thêm R.drawable.ic_clearhoặc biểu tượng rõ ràng lúc đầu. Cái này là từ google- https: // m Material.io/tools/icons/?icon=clear&style=baseline


Nếu bạn chèn this.clearFocus()trước câu trả lời đúng, bạn có thể nghe sự kiện này trên trình gọi EditText với onFocusChangengười nghe
Joost Schepel

Thật tuyệt vời, chỉ có vấn đề là tôi đã đặt biểu tượng bên trái có thể vẽ trong AppCompatEditText và nó sẽ xóa khi tôi gọi chức năng này, bạn có thể cho tôi biết vấn đề này không?
Arbaz.in

@ Arbaz.in Đó là vì phương thức gọi setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0). Bạn có thể chuyển id biểu tượng có thể vẽ bên trái dưới dạng tham số mới cho hàm này và đặt nó trong cuộc gọi.
Gul Sơn

@Gulshan tôi đã làm như vậy vẫn còn gỡ bỏ được
Arbaz.in

20

Bộ phận hỗ trợ của Android có một SearchView lớp thực hiện chính xác điều này. ( EditTextMặc dù không xuất phát từ đó, vì vậy phải sử dụng SearchView.OnQueryTextListenerthay vì a TextWatcher)

Chế độ xem tìm kiếm không có văn bản (và văn bản gợi ý "Tìm kiếm")

nhập mô tả hình ảnh ở đây

Sử dụng trong XML như vậy:

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

trong đó, x là:

nhập mô tả hình ảnh ở đây


8
Vẫn cần gán một onClickListener phải không? Một tìm kiếm nhanh đã cho tôi điều này . Đoán giải pháp tốt hơn là đi với Framelayout. Cảm ơn mặc dù!
VenoM


6

Nếu bạn không muốn sử dụng chế độ xem tùy chỉnh hoặc bố cục đặc biệt, bạn có thể sử dụng bản vá 9 để tạo nút (X).

Ví dụ: http://postimg.org/image/tssjmt97p/ (Tôi không có đủ điểm để đăng ảnh trên StackOverflow)

Giao điểm của các pixel đen bên phải và dưới cùng đại diện cho khu vực nội dung. Bất cứ điều gì bên ngoài khu vực đó là đệm. Vì vậy, để phát hiện người dùng đã nhấp vào x, bạn có thể đặt OnTouchListener như vậy:

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

Theo nhu cầu của bạn, giải pháp này có thể hoạt động tốt hơn trong một số trường hợp. Tôi thích giữ xml của tôi ít phức tạp hơn. Điều này cũng hữu ích nếu bạn muốn có một biểu tượng ở bên trái, vì bạn có thể chỉ cần đưa nó vào bản vá 9.


4

Tôi đã làm phần UI như bên dưới:

<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.pngnhập mô tả hình ảnh ở đây

Nút ẩn / Xóa nút / hiển thị:

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

Xử lý nội dung tìm kiếm (nghĩa là khi người dùng nhấp vào tìm kiếm từ bảng phím mềm)

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

Nút xóa / chéo

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


2

Đây là thư viện hoàn chỉnh với tiện ích: https://github.com/opprime/EditTextField

Để sử dụng nó, bạn nên thêm phụ thuộc:

compile 'com.optimus:editTextField:0.2.0'

Trong tệp layout.xml, bạn có thể chơi với các cài đặt widget:

xmlns:app="http://schemas.android.com/apk/res-auto"
  • ứng dụng: clearButtonMode có thể có các giá trị như vậy: không bao giờ luôn trong khi Chỉnh sửa trừ khi Chỉnh sửa

  • ứng dụng: clearButtonDrawable

Mẫu trong hành động:

nhập mô tả hình ảnh ở đây


2

Chỉ cần đặt gần giống như drawableEndtrong của bạn EditText:

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

và sử dụng tiện ích mở rộng để xử lý nhấp chuột (hoặc sử dụng OnTouchListenertrực tiếp trên của bạn 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
    }
}

sử dụng mở rộng:

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

1

Bạn có thể sử dụng đoạn trích này với câu trả lời của Jaydip cho nhiều hơn một nút. chỉ cần gọi nó sau khi nhận được một tham chiếu đến các yếu tố ET và nút. Tôi đã sử dụng nút vecotr để bạn phải thay đổi thành phần Nút thành 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

Nếu bạn đang ở trong bố cục khung hoặc bạn có thể tạo bố cục khung tôi đã thử một cách tiếp cận khác ....

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

Đây là một văn bản chỉnh sửa trong đó tôi đặt biểu tượng chéo là có thể vẽ được và hơn UPON, tôi đặt một nút trong suốt để xóa văn bản.


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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.