如何使用十字(x)按钮创建EditText?


198

是否有任何类似EditText包含十字形按钮的小部件,或者是否有为其EditText自动创建的属性?我希望十字按钮删除任何用编写的文本EditText


2
似乎不是任何标准小部件。但是,通过Google搜索“ android edittext clear button x”,您发现了几种不同的方法。因此,我猜他们称之为“清除按钮”。另外,看到这个回答一个相关的问题:stackoverflow.com/questions/4175398/clear-edittext-on-click/...
HostileFork表示不信任SE

你可以在这里下载源:github.com/GhOsTTT/editTextXbutton有一个愉快的一天
格克汗Musapaşaoğluヅ

实质上是重复的另一个问题是在Android中实现uitextfield属性
Alex Cohn

Answers:


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>

您还可以使用按钮的ID并对其onClickListener方法执行所需的任何操作。


8
这是一种低效的方法。扬琴科的答案是使用复合画图的正确方法。
numan salati 2013年

4
如果您恰巧选择此解决方案,并且注意到图像拉伸得太多,则可能应该使用ImageButton而不是常规的Button。
personne3000

3
尽管此解决方案“效率低下”,但盲人用户可以更轻松地访问它。使用drawable将迫使您的用户执行非常复杂的操作来清除文本-看到用户可以使用X按钮快速进行操作。
Daniel Monteiro'9

2
这是什么效率低下?
丹尼

121

如果你碰巧使用DroidParts,我刚刚加入ClearableEditText

这是abs__ic_clear_holo_lightActionBarSherlock设置为的自定义背景和清除图标的外观:

在此处输入图片说明


11
最好的解决方案,因为该类可以扩展EditText。THX @yanchenko
tbruyelle

2
@stephanek。我已经在开发分支中修复了该问题,它将成为1.4.3版本的一部分。
扬琴科

4
谢谢!如果您还可以在DroidParts中包含ClearableAutoCompleteTextView,那将真的很酷。对于其他也尝试这样做的用户:使用DroidParts库,从ClearableEditText复制代码,然后扩展AutoCompleteTextView。
RobinDeCroon 2014年

2
这是炸弹!您也可以单独使用它,通过普通的TextWatcher更改TextWatcherAdapter依赖性。
Pimentoso

1
@yanchenko看了您的实现。似乎在可接受的触摸区域非常小和具有大于默认高度的编辑文本之间接受了一些折衷,该默认高度接受沿编辑文本内y轴的所有触摸事件。您的实现是前者,而我是后者。在类似情况下,您建议这样做吗?例如,选择一个可能会被误按的较小的点击框,或者选择一个较大的点击框,在此框中,随着文本的扩大或较大,按下的内容可能会超出可绘制对象的范围。
Jack.Ramsden '16

63

通过适用于Android的Material Design Components的2020解决方案:

将材料组件添加到您的gradle设置中:

从此处查找最新版本:https//maven.google.com/

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

或者,如果您尚未更新为使用AndroidX库,则可以通过以下方式添加它:

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(竖起大拇指)
kevoroid

请确保通读文档,因为尚不支持所有xml属性。您可能必须仔细查看源代码或提交消息,因为有时有时会出现确切的实现细节。对于自定义endIcon,我遇到了此类问题。一条提交消息显示xml属性尚无实现支持它。在实施完成之前,将不得不使用其他方法
M. Smith,

2020
Sam Chen

app:endIconMode =“ clear_text”是否适用<androidx.appcompat.widget.AppCompatEditText/>?您能帮我吗
Arbaz.in

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

顺便说一句,您必须首先添加R.drawable.ic_clear或清除图标。这是来自google- https://material.io/tools/icons/?icon=clear&style=baseline


如果this.clearFocus()在return true语句之前插入,则可以使用侦听器在EditText调用器上onFocusChange侦听此事件
Joost Schepel

太好了,唯一的问题是我在AppCompatEditText中设置了可绘制的左图标,当我调用此函数时它将被删除,请您告诉我是什么问题?
Arbaz.in

@ Arbaz.in是因为调用方法setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0)。您可以将左可绘制图标id作为新参数传递给此函数,并将其放入调用中。
Gulshan

@Gulshan我已经做过同样的事情,仍然删除了该可绘制对象
Arbaz.in

20

Android的支持库有一个SearchView完全可以做到这一点的类。(EditText尽管不是派生的,所以必须使用a SearchView.OnQueryTextListener而不是a 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;
        }
    });`

清除/交叉按钮

  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"
  • app:clearButtonMode,可以具有以下值:除非编辑,否则永远不会在编辑时

  • app: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和Button元素的引用后,只需调用它即可。我使用了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"
    />

这是一个编辑文本,在其中我将一个十字图标作为可绘制的右图,然后,在UPON中,我放置了一个透明按钮以清除文本。


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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.