Is there any widget like EditText
which contains a cross button, or is there any property for EditText
by which it is created automatically? I want the cross button to delete whatever text written in EditText
.
This question is related to
android
android-edittext
Here is the simple complete solution in kotlin.
This whole layout will be your search bar
<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>
Now this is the functionality of clear button, paste this code in onCreate method.
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
}
}
})
Here is complete library with the widget: https://github.com/opprime/EditTextField
To use it you should add the dependency:
compile 'com.optimus:editTextField:0.2.0'
In the layout.xml file you can play with the widget settings:
xmlns:app="http://schemas.android.com/apk/res-auto"
app:clearButtonMode,can has such values: never always whileEditing unlessEditing
app:clearButtonDrawable
Sample in action:
I did the UI part like below:
<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>
Cross/Clear button hide/show:
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) {}
});
Handle search stuffs (i.e when user clicks search from soft key board)
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 button
clearSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
searchBox.setText("");
}
});
This is a kotlin solution. Put this helper method in some kotlin file-
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
})
}
And then use it as following in the onCreate
method and you should be good to go-
yourEditText.setupClearButtonWithAction()
BTW, you have to add R.drawable.ic_clear
or the clear icon at first. This one is from google- https://material.io/tools/icons/?icon=clear&style=baseline
You can use this snippet with Jaydip answer for more than one button. just call it after getting a reference to the ET and Button Elements. I used vecotr button so you have to change the Button element to 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);
}
}
});
}
If you are in frame layout or you can create a frame layout I tried another approach....
<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"
/>
This is an edit text where I put a cross icon as a right drawable and than UPON it I put a transparent button which clears text.
For drawable resource
you can use standard android images :
http://androiddrawables.com/Menu.html
For example :
android:background="@android:drawable/ic_menu_close_clear_cancel"
2020 solution via Material Design Components for Android:
Add Material Components to your gradle setup:
Look for latest version from here: https://maven.google.com/
implementation 'com.google.android.material:material:1.1.0'
or if you havent updated to using AndroidX libs, you can add it this way:
implementation 'com.android.support:design:28.0.0'
Then
<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>
Pay attention to: app:endIconMode="clear_text"
As discussed here Material design docs
Use
android:drawableRight="@android:drawable/ic_input_delete"
If you happen to use DroidParts, I've just added ClearableEditText.
Here's what it looks like with a custom background & clear icon set to abs__ic_clear_holo_light
from ActionBarSherlock:
Drawable x = getResources().getDrawable(R.drawable.x);
x.setBounds(0, 0, x.getIntrinsicWidth(), x.getIntrinsicHeight());
mEditText.setCompoundDrawables(null, null, x, null);
where, x is:
Just put close cross like drawableEnd
in your EditText
:
<EditText
...
android:drawableEnd="@drawable/ic_close"
android:drawablePadding="8dp"
... />
and use extension to handle click (or use OnTouchListener
directly on your 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
}
}
extension usage:
editText.onDrawableEndClick {
// TODO clear action
etSearch.setText("")
}
Android's support libarary has a SearchView
class that does exactly this. (Not derrived from EditText
though, so have to use a SearchView.OnQueryTextListener
instead of a TextWatcher
)
Use in XML like so:
<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" />
If you don't want to use custom views or special layouts, you can use 9-patch to make the (X) button .
Example: http://postimg.org/image/tssjmt97p/ (I don't have enough points to post images on StackOverflow)
The intersection of the right and bottom black pixels represent the content area. Anything outside of that area is padding. So to detect that the user clicked on the x you can set a OnTouchListener like so:
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;
}
});
According to your needs this solution can work better in some cases. I prefer to keep my xml less complicated. This also helps if you want to have an icon on the left, as you can simply include it in the 9 patch.
<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;
}
Clear text:
"Text field with a clear text trailing icon."
If set, an icon is displayed when text is present and pressing it clears the input text.
...
app:endIconMode="clear_text">
?
...
?
</com.google.android.material.textfield.TextInputLayout>
I leave it here:
Source: Stackoverflow.com