如何在它的末尾创建带有十字(x)按钮的EditText?

问题描述 投票:0回答:18

是否有像

EditText
这样包含十字按钮的小部件,或者是否有
EditText
的任何属性可以自动创建它?我想要十字按钮删除写在
EditText
.

中的任何文本
android android-edittext
18个回答
170
投票

使用以下布局:

<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 方法上执行您想要的任何操作。


164
投票

2020 通过 Material Design Components for Android 解决方案:

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

从这里查找最新版本:https://maven.google.com/

implementation 'com.google.android.material:material:1.3.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"

如这里所讨论材料设计文档


121
投票

如果您碰巧使用DroidParts,我刚刚添加了ClearableEditText

这是自定义背景和清晰图标设置为

abs__ic_clear_holo_light
来自 ActionBarSherlock 的样子:

enter image description here


37
投票

这是一个 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://fonts.google.com/icons?selected=Material%20Icons%20Outlined%3Aclear%3A


24
投票

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

15
投票
Drawable x = getResources().getDrawable(R.drawable.x);
x.setBounds(0, 0, x.getIntrinsicWidth(), x.getIntrinsicHeight());
mEditText.setCompoundDrawables(null, null, x, null);

其中,x是:

enter image description here


13
投票

对于

drawable resource
你可以使用标准的android图像:

http://androiddrawables.com/Menu.html 的网络存档

例如:

android:background="@android:drawable/ic_menu_close_clear_cancel"

7
投票

如果你不想使用自定义视图或特殊布局,你可以使用 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 补丁中。


6
投票

只需像

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

6
投票

明文:

“带有清晰文本尾随图标的文本字段。”

如果设置,当文本出现时会显示一个图标,按下它会清除输入的文本。

    ...
    app:endIconMode="clear_text">
​
    ...
​
</com.google.android.material.textfield.TextInputLayout>

我把它留在这里:

material.io

例子


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"?>
<!-- res/drawable/rounded_edittext_focused.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:shape="rectangle" >

    <solid android:color="#FFFFFF" />

    <stroke
        android:width="1dp"
        android:color="#C9C9CE" />

    <corners
        android:bottomLeftRadius="15dp"
        android:bottomRightRadius="15dp"
        android:topLeftRadius="15dp"
        android:topRightRadius="15dp" />

</shape>

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

3
投票

这是带有小部件的完整库: 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
投票

使用

android:drawableRight="@android:drawable/ic_input_delete"

1
投票

您可以将此片段与 Jaydip answer 一起用于多个按钮。在获得对 ET 和按钮元素的引用后调用它。我使用了 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;
}

0
投票

这是 kotlin 中简单的完整解决方案。

整个布局将成为您的搜索栏

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="35dp"
        android:layout_margin="10dp"
        android:background="@drawable/your_desired_drawable">

        <EditText
            android:id="@+id/search_et"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_toStartOf="@id/clear_btn"
            android:background="@null"
            android:hint="search..."
            android:imeOptions="actionSearch"
            android:inputType="text"
            android:maxLines="1"
            android:paddingStart="15dp"
            android:paddingEnd="10dp" />

        <ImageView
            android:id="@+id/clear_btn"
            android:layout_width="20dp"
            android:layout_height="match_parent"
            android:layout_alignParentEnd="true"
            android:layout_centerInParent="true"
            android:layout_marginEnd="15dp"
            android:visibility="gone"
            android:src="@drawable/ic_baseline_clear_24"/>

    </RelativeLayout>

现在这是清除按钮的功能,将这段代码粘贴到 onCreate 方法中。

search_et.addTextChangedListener(object: TextWatcher {
            override fun beforeTextChanged(s:CharSequence, start:Int, count:Int, after:Int) {
            }
            override fun onTextChanged(s:CharSequence, start:Int, before:Int, count:Int) {
            }
            override fun afterTextChanged(s: Editable) {
                if (s.isNotEmpty()){
                    clear_btn.visibility = VISIBLE
                    clear_btn.setOnClickListener {
                        search_et.text.clear()
                    }
                }else{
                    clear_btn.visibility = GONE
                }
            }
        })

0
投票

这是使用关闭图标和 gettextcleanlistener 创建自定义可清除编辑文本的最佳方式

class EditTextWithClear : AppCompatEditText {

constructor(context: Context) : super(context)

constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)

constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
    context,
    attributeSet,
    defStyleAttr
)

private val blackClearDrawable =
    ResourcesCompat.getDrawable(resources, R.drawable.ic_clear_text, null) as Drawable
private val opaqueClearDrawable =
    ResourcesCompat.getDrawable(resources, R.drawable.ic_clear_text, null) as Drawable

private var clearButtonImage: Drawable = opaqueClearDrawable
private var onTextClearListener: OnTextClearListener? = null

fun setOnTextClearListener(onTextClearListener: OnTextClearListener) {
    this.onTextClearListener = onTextClearListener
}

private fun showClearButton() {
    setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, clearButtonImage, null)
}

private fun hideClearButton() {
    setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null)
}

@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
    if (isClearButtonVisible() && wasClearButtonTouched(event)) {
        onClearButtonTouched(event)
        return true
    }

    return super.onTouchEvent(event)
}

override fun onTextChanged(
    text: CharSequence?,
    start: Int,
    lengthBefore: Int,
    lengthAfter: Int
) {
    if (text?.isNotEmpty() == true) {
        showClearButton()
    } else {
        onTextClearListener?.onTextClearListener()
        hideClearButton()
    }
}

private fun isClearButtonVisible(): Boolean {
    return compoundDrawablesRelative[2] != null
}

private fun wasClearButtonTouched(event: MotionEvent): Boolean {
    val isClearButtonAtTheStart = layoutDirection == View.LAYOUT_DIRECTION_RTL

    return if (isClearButtonAtTheStart) {

        val clearButtonEnd = paddingStart + clearButtonImage.intrinsicWidth
        event.x < clearButtonEnd

    } else {

        val clearButtonStart = width - clearButtonImage.intrinsicWidth - paddingEnd
        event.x > clearButtonStart

    }
}

private fun onClearButtonTouched(event: MotionEvent) {
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            clearButtonImage = blackClearDrawable
            showClearButton()
        }
        MotionEvent.ACTION_UP -> {
            clearButtonImage = opaqueClearDrawable
            text?.clear()
            hideClearButton()
        }
    }
}

interface OnTextClearListener {
    fun onTextClearListener()
}

/*
This code use your activity and fragment
editext.setOnTextClearListener(object : EditTextWithClear.OnTextClearListener{
    override fun onTextClearListener() {
        //perform action when empty your edittext
    }
})*/}

XML代码

<com.example.clearbaleedittext.utility.EditTextWithClear
    android:id="@+id/etEditext"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/dp_12"
    android:background="@color/transparent"
    android:fontFamily="@font/helvetica_normal"
    android:inputType="text"
    android:maxLines="1"
    android:paddingHorizontal="@dimen/dp_12"
    android:paddingVertical="@dimen/dp_12"
    android:textSize="@dimen/sp_16"
    />
© www.soinside.com 2019 - 2024. All rights reserved.