วิธีสร้าง EditText ด้วยปุ่ม cross (x) ที่ส่วนท้ายของมัน?


198

มีวิดเจ็ตEditTextที่มีปุ่มกากบาทหรือมีคุณสมบัติใดEditTextที่มันถูกสร้างขึ้นโดยอัตโนมัติหรือไม่? EditTextฉันต้องการปุ่มข้ามในการลบข้อความที่เขียนใน


2
ดูเหมือนจะไม่เป็นเครื่องมือมาตรฐานสำหรับมัน แต่คุณจะพบวิธีที่แตกต่างกันเล็กน้อยในการค้นหาโดย Google สำหรับ "android edittext clear button x" ดังนั้นฉันเดาว่า "ปุ่มที่ชัดเจน" คือสิ่งที่พวกเขาเรียกมัน โปรดดูคำตอบสำหรับคำถามที่เกี่ยวข้อง: stackoverflow.com/questions/4175398/clear-edittext-on-click/?hl=th
HostileFork พูดว่าอย่าเชื่อถือ SE

คุณสามารถดาวน์โหลดซอร์สได้ที่นี่: github.com/GhOsTTT/editTextXbutton ขอให้มีความสุขมาก ๆ ในวันนี้
GökhanMusapaşaoğluヅ

อีกคำถามหนึ่งที่มีความซ้ำซ้อนก็คือการนำคุณสมบัติของ uitextfield มาใช้ใน Android
Alex Cohn

คำตอบ:


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
นี่เป็นวิธีที่ไม่มีประสิทธิภาพในการทำ คำตอบของ yanchenko เป็นแนวทางที่ถูกต้องในการใช้ drawable ผสม
numan salati

4
หากคุณเลือกวิธีการแก้ไขนี้และสังเกตว่าภาพถูกยืดออกมากเกินไปคุณควรใช้ ImageButton แทนปุ่มปกติ
personne3000

3
แม้ว่าโซลูชันนี้จะ "ไม่มีประสิทธิภาพ" แต่ผู้ใช้ที่ตาบอดสามารถเข้าถึงได้มากขึ้น การใช้ drawable จะบังคับให้ผู้ใช้ดำเนินการที่ซับซ้อนมากเพื่อล้างข้อความ - สิ่งที่ผู้ใช้เห็นสามารถทำได้อย่างรวดเร็วด้วยปุ่ม X
Daniel Monteiro

2
การไร้ประสิทธิภาพเกี่ยวกับเรื่องนี้คืออะไร?
Denny

121

หากคุณเกิดขึ้นกับการใช้DroidPartsผมเพิ่งเพิ่มClearableEditText

นี่คือสิ่งที่ดูเหมือนกับพื้นหลังที่กำหนดเอง & ไอคอนที่ชัดเจนที่ตั้งค่าabs__ic_clear_holo_lightจากActionBarSherlock :

ป้อนคำอธิบายรูปภาพที่นี่


11
EditTextทางออกที่ดีที่สุดเพราะระดับขยาย ขอบคุณ @yanchenko
tbruyelle

2
@stephanek ฉันได้แก้ไขเรื่องนี้ในสาขาพัฒนาแล้วจะเป็นส่วนหนึ่งของรุ่น 1.4.3
yanchenko

4
ขอบคุณ! มันจะเจ๋งจริง ๆ แต่ถ้าคุณสามารถรวม ClearableAutoCompleteTextView ใน DroidParts สำหรับผู้ใช้รายอื่นที่พยายามทำสิ่งนี้: ใช้ไลบรารี DroidParts ให้คัดลอกโค้ดจาก ClearableEditText และเพียงขยาย AutoCompleteTextView
RobinDeCroon

2
นี่คือระเบิด! คุณยังสามารถใช้แบบสแตนด์อโลนเพื่อเปลี่ยนการพึ่งพา TextWatcherAdapter ด้วย TextWatcher ปกติ
Pimentoso

1
@yanchenko ลองดูที่การใช้งานของคุณ ดูเหมือนว่ามีการแลกเปลี่ยนเล็กน้อยระหว่างพื้นที่สัมผัสที่ยอมรับได้ค่อนข้างเล็กและมีข้อความแก้ไขที่มีความสูงมากกว่าค่าเริ่มต้นที่ยอมรับเหตุการณ์สัมผัสตลอดแนวแกน y ภายในข้อความแก้ไข การใช้งานของคุณคืออดีตและขุดในภายหลัง ในสถานการณ์ที่คล้ายคลึงกันคุณอยากจะแนะนำให้ทำเช่นเดียวกัน? เช่นไปสำหรับกล่องที่มีขนาดเล็กกว่าที่สามารถกดหรือมีขนาดใหญ่กว่ากล่องที่มีข้อความแก้ไขขยายหรือขนาดใหญ่ที่กดอาจจะดีนอกขอบเขตของ drawable
Jack.Ramsden

67

โซลูชัน 2020 ผ่านองค์ประกอบการออกแบบวัสดุสำหรับ Android:

เพิ่มส่วนประกอบวัสดุในการตั้งค่าการไล่ระดับสีของคุณ:

ค้นหาเวอร์ชันล่าสุดจากที่นี่: 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>

ให้ความสนใจกับ: แอพ: endIconMode = "clear_text"

ตามที่กล่าวไว้ที่นี่เอกสารการออกแบบวัสดุ


10
นี่ควรเป็นคำตอบที่ยอมรับใหม่ ในกรณีของฉันฉันไม่สามารถใช้งานได้หากไม่อัปเดตเป็นห้องสมุด AndroidX
Ben

@Ben (ยกนิ้ว)
kevoroid

โปรดอ่านเอกสารอย่างละเอียดเนื่องจากยังไม่รองรับแอตทริบิวต์ xml ทั้งหมด คุณอาจต้องค้นหาแหล่งที่มาหรือส่งข้อความเนื่องจากบางครั้งมีรายละเอียดการใช้งานที่แน่นอน ฉันมีปัญหาประเภทนี้สำหรับ endIcon ที่กำหนดเอง ข้อความคอมมิชชันเปิดเผยว่าแอ็ตทริบิวต์ xml ยังไม่มีการนำไปใช้งาน จะต้องใช้วิธีการอื่นจนกว่าการดำเนินการจะเสร็จสิ้น
M. Smith

คำตอบที่ดีที่สุดในปี 2020
แซมเฉิน

แอพพลิเคชั่น: endIconMode = "clear_text" สามารถใช้งานได้<androidx.appcompat.widget.AppCompatEditText/>หรือไม่ คุณช่วยฉันด้วยเหมือนกันได้
ไหม

32

นี่เป็นวิธีแก้ปัญหา kotlin ใส่วิธีการช่วยเหลือนี้ในบางไฟล์ 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()

BTW คุณจะต้องเพิ่มR.drawable.ic_clearหรือไอคอนที่ชัดเจนในตอนแรก อันนี้มาจาก google- https://material.io/tools/icons/?icon=clear&style=baseline


หากคุณแทรกthis.clearFocus()ก่อนที่จะส่งกลับคำสั่งที่แท้จริงคุณสามารถฟังเหตุการณ์นี้ในการโทร EditText กับonFocusChangeผู้ฟัง
Joost Schepel

เยี่ยมมากมันเป็นปัญหาเฉพาะคือฉันตั้งไอคอนด้านซ้ายที่สามารถถอดออกได้ใน AppCompatEditText และมันจะลบออกเมื่อฉันเรียก funcion นี้คุณช่วยบอกฉันทีว่าปัญหาคืออะไร?
Arbaz.in

@ Arbaz.in setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0)มันเป็นเพราะวิธีการโทร คุณสามารถส่ง id ไอคอนที่วาดได้ด้านซ้ายเป็นพารามิเตอร์ใหม่ไปยังฟังก์ชันนี้และวางไว้ในการโทร
Gulshan

@Gulshan ฉันได้ทำเช่นเดียวกันยังลบที่ drawable
Arbaz.in

20

libarary รองรับ Android มีSearchViewคลาสที่ทำสิ่งนี้ (ไม่ได้ถูกสกัดกั้นจากEditTextแม้ว่าดังนั้นต้องใช้ a 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-patch เพื่อสร้างปุ่ม (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

ฉันทำส่วน UI ดังนี้:

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

ปุ่ม Clear / Cross

  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

คุณสามารถใช้ตัวอย่างนี้กับคำตอบ Jaydip มากกว่าหนึ่งปุ่ม เพียงแค่เรียกมันหลังจากได้รับการอ้างอิงถึง ET และองค์ประกอบของปุ่ม ฉันใช้ปุ่ม vecotr ดังนั้นคุณต้องเปลี่ยนองค์ประกอบปุ่มเป็น 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"
    />

นี่คือข้อความแก้ไขที่ฉันใส่ไอคอนไขว้เป็น drawable ที่ถูกต้องและกว่านั้นฉันใส่ปุ่มโปร่งใสที่ล้างข้อความ


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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.