问题
I have created an EditText
for search, which contains on the left side a search icon and on the right side of icon:
<EditText
android:id="@+id/Search"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:drawableLeft="@android:drawable/ic_menu_search"
android:drawableRight="@android:drawable/ic_delete"
android:hint="Search Product .." >
</EditText>
I want to know how can I clear the content of EditText
when I click the cross button.
Thank you in advance.
回答1:
An improved answer by @aristo_sh from Handling click events on a drawable within an EditText
mQueryEditText.setOnTouchListener(new OnTouchListener() {
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_BOTTOM = 3;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
int leftEdgeOfRightDrawable = mQueryEditText.getRight()
- mQueryEditText.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width();
// when EditBox has padding, adjust leftEdge like
// leftEdgeOfRightDrawable -= getResources().getDimension(R.dimen.edittext_padding_left_right);
if (event.getRawX() >= leftEdgeOfRightDrawable) {
// clicked on clear icon
mQueryEditText.setText("");
return true;
}
}
return false;
}
});
回答2:
I prefer using another custome Edittex
as below clearable edittext. You can use it in xml as normal edittext. To listen to clear event, you can setListener
for your ClearableEdittext
/** Copyright 2014 Alex Yanchenko
* To change clear icon, set
* <p/>
* <pre>
* android:drawableRight="@drawable/custom_icon"
* </pre>
*/
public class ClearableEditText extends EditText implements OnTouchListener,
OnFocusChangeListener, TextWatcherAdapter.TextWatcherListener {
public interface Listener {
void didClearText();
}
public void setListener(Listener listener) {
this.listener = listener;
}
private Drawable xD;
private Listener listener;
public ClearableEditText(Context context) {
super(context);
init();
}
public ClearableEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ClearableEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
@Override
public void setOnTouchListener(OnTouchListener l) {
this.l = l;
}
@Override
public void setOnFocusChangeListener(OnFocusChangeListener f) {
this.f = f;
}
private OnTouchListener l;
private OnFocusChangeListener f;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (getCompoundDrawables()[2] != null) {
boolean tappedX = event.getX() > (getWidth() - getPaddingRight() - xD
.getIntrinsicWidth());
if (tappedX) {
if (event.getAction() == MotionEvent.ACTION_UP) {
setText("");
if (listener != null) {
listener.didClearText();
}
}
return true;
}
}
if (l != null) {
return l.onTouch(v, event);
}
return false;
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
setClearIconVisible(!TextUtils.isEmpty(getText()));
} else {
setClearIconVisible(false);
}
if (f != null) {
f.onFocusChange(v, hasFocus);
}
}
@Override
public void onTextChanged(EditText view, String text) {
if (isFocused()) {
setClearIconVisible(!TextUtils.isEmpty(text));
}
}
private void init() {
xD = getCompoundDrawables()[2];
if (xD == null) {
xD = getResources()
.getDrawable(android.R.drawable.presence_offline);
}
xD.setBounds(0, 0, xD.getIntrinsicWidth(), xD.getIntrinsicHeight());
setClearIconVisible(false);
super.setOnTouchListener(this);
super.setOnFocusChangeListener(this);
addTextChangedListener(new TextWatcherAdapter(this, this));
}
protected void setClearIconVisible(boolean visible) {
Drawable x = visible ? xD : null;
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], x, getCompoundDrawables()[3]);
}
}
Edit: I forgot TextWatcherAdapter
, actually it's only custome TextWatcher
:
public class TextWatcherAdapter implements TextWatcher {
public interface TextWatcherListener {
void onTextChanged(EditText view, String text);
}
private final EditText view;
private final TextWatcherListener listener;
public TextWatcherAdapter(EditText editText, TextWatcherListener listener) {
this.view = editText;
this.listener = listener;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
listener.onTextChanged(view, s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// pass
}
@Override
public void afterTextChanged(Editable s) {
// pass
}
}
回答3:
Try this:
activity_main.xml
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:padding="5dp">
<EditText
android:id="@+id/Search"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:drawableLeft="@android:drawable/ic_menu_search"
android:hint="Search Product .." >
</EditText>
<Button
android:id="@+id/clearText"
android:layout_width="23dp"
android:layout_height="23dp"
android:layout_marginRight="10dp"
android:layout_gravity="right|bottom"
android:layout_marginBottom="10dp"
android:background="@android:drawable/ic_delete"
android:onClick="clear"/>
</FrameLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
EditText mEditText;
Button mClearText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = (EditText) findViewById(R.id.Search);
mClearText = (Button) findViewById(R.id.clearText);
//initially clear button is invisible
mClearText.setVisibility(View.INVISIBLE);
//clear button visibility on text change
mEditText.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
//do nothing
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//do nothing
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.length() != 0) {
mClearText.setVisibility(View.VISIBLE);
} else {
mClearText.setVisibility(View.GONE);
}
}
});
}
//clear button onclick
public void clear(View view) {
mEditText.setText("");
mClearText.setVisibility(View.GONE);
}
}
回答4:
Exemple I made:
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP){
// 100 is a fix value for the moment but you can change it
// according to your view
if (motionEvent.getX()>(view.getWidth()-100)){
((EditText)view).setText("");
}
}
return false;
}
});
mPasswordView.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.toString().trim().length()==0){
mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
} else {
mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_black_24dp, 0);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
if (s.toString().trim().length() == 0) {
mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
} else {
mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_black_24dp, 0);
}
}
});
回答5:
The answer of Paul Verest isn't bad, but doesn't take padding into account. Here's an example (in Kotlin) for left and right clicks, including padding of the editText (which shifts the drawable relative from the sides of the editText).
editText.setOnTouchListener(View.OnTouchListener { _, event ->
val DRAWABLE_LEFT = 0
val DRAWABLE_RIGHT = 2
if (event.action == MotionEvent.ACTION_UP) {
if (event.x <= editText.compoundDrawables[DRAWABLE_LEFT].bounds.width() + (2 * editText.paddingStart)) {
// Left drawable clicked
return@OnTouchListener true
}
if (event.x >= editText.right - editText.compoundDrawables[DRAWABLE_RIGHT].bounds.width() - (2 * editText.paddingEnd)) {
// Right drawable clicked
return@OnTouchListener true
}
}
false
})
Notes:
- I use
event.x
instead ofevent.rawX
to get the click location.event.rawX
is the raw X coordinate on the screen, it doesn't take the location of the editText into account (eg. margins that precent the editText from clipping the screen sides).event.x
is the x coordinate relative to the left bound of the editText itself, which makes the calculations easier to understand. - Always take padding into account when making elements clickable! Of course, if you shift the drawable too far using the editText padding, then it doesn't make sense to make the complete padding clickable. In my case it works well to use the
editText.paddingStart
twice, so it's clickable for both sides of the drawable. You might consider using this padding once for the left side of the starting-drawable only, and add theeditText.compoundDrawablePadding
- which is the padding between drawable and text - for the right side padding. Of course you can also use some constant dp values, depending on your own preference. The concept of clickable padding is explained very well in this blog.
来源:https://stackoverflow.com/questions/23184120/android-how-to-clear-an-edittext-by-cross-button-in-the-right-side