我已经在EditText小部件中添加了文本右侧的图像,使用以下XML:

<EditText
  android:id="@+id/txtsearch"
  ...
  android:layout_gravity="center_vertical"
  android:background="@layout/shape"
  android:hint="Enter place,city,state"
  android:drawableRight="@drawable/cross" />

但我想在单击嵌入图像时清除EditText。我该怎么做呢?


当前回答

我见过几个解决方案,但没有一个能说服我。要么非常复杂,要么太简单(不可重用)。

这是我目前最喜欢的方法:

mEditText.setOnTouchListener(
        new OnEditTextRightDrawableTouchListener(mEditText) {
          @Override
          public void OnDrawableClick() {
            // The right drawable was clicked. Your action goes here.
          }
        });

这是可重复使用的触摸监听器:

import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.EditText;

public abstract class OnEditTextRightDrawableTouchListener implements OnTouchListener {

  private final EditText mEditText;

  public OnEditTextRightDrawableTouchListener(@NonNull final EditText editText) {
    mEditText = editText;
  }

  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
    if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
      final int DRAWABLE_RIGHT_POSITION = 2;
      final Drawable drawable = mEditText.getCompoundDrawables()[DRAWABLE_RIGHT_POSITION];
      if (drawable != null) {
        final float touchEventX = motionEvent.getX();
        final int touchAreaRight = mEditText.getRight();
        final int touchAreaLeft = touchAreaRight - drawable.getBounds().width();
        if (touchEventX >= touchAreaLeft && touchEventX <= touchAreaRight) {
          view.performClick();
          OnDrawableClick();
        }
        return true;
      }
    }
    return false;
  }

  public abstract void OnDrawableClick();
}

你可以在这里看到要点。

其他回答

Kotlin是一种很棒的语言,每个类都可以使用新方法进行扩展。让我们为EditText类介绍一个新方法,它将捕捉点击到右绘图。

fun EditText.onRightDrawableClicked(onClicked: (view: EditText) -> Unit) {
this.setOnTouchListener { v, event ->
    var hasConsumed = false
    if (v is EditText) {
        if (event.x >= v.width - v.totalPaddingRight) {
            if (event.action == MotionEvent.ACTION_UP) {
                onClicked(this)
            }
            hasConsumed = true
        }
    }
    hasConsumed
}
}

你可以看到它以回调函数作为参数,当用户单击右可绘制时调用。

val username = findViewById<EditText>(R.id.username_text)
    username.onRightDrawableClicked {
        it.text.clear()
    }

我已经采取了@AZ_的解决方案,并将其转换为kotlin扩展函数:

所以在代码中复制这个:

@SuppressLint("ClickableViewAccessibility")
fun EditText.setDrawableRightTouch(setClickListener: () -> Unit) {
    this.setOnTouchListener(View.OnTouchListener { _, event ->
        val DRAWABLE_LEFT = 0
        val DRAWABLE_TOP = 1
        val DRAWABLE_RIGHT = 2
        val DRAWABLE_BOTTOM = 3
        if (event.action == MotionEvent.ACTION_UP) {
            if (event.rawX >= this.right - this.compoundDrawables[DRAWABLE_RIGHT].bounds.width()
            ) {
                setClickListener()
                return@OnTouchListener true
            }
        }
        false
    })
}

你可以在EditText上调用setDrawableRightTouch函数来使用它:

yourEditText.setDrawableRightTouch {
    //your code
}

上述问题的一个可能的解决方案是使用android的新材质组件TextInputLayout。

<com.google.android.material.textfield.TextInputLayout
                    android:id="@+id/searchInput"
                    style="@style/Widget.App.TextInputLayout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/search"
                    app:endIconMode="custom"
                    app:endIconContentDescription="Search"
                    app:endIconDrawable="@drawable/ic_search">

                    <EditText
                        android:id="@+id/et_search"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"/>

                </com.google.android.material.textfield.TextInputLayout>

在这里设置TextInputLayout属性endIconMode时,将一个按钮放置在所包含的EditText的末尾。

另外app:endIconMode = "custom"允许自定义图标的点击功能

最后,为了监听结束图标单击,调用外围TextInputLayout组件上的setEndIconClickListener()。

我使用了一个简短的解决方案,甚至适用于对话的片段。

            //The listener of a drawableEnd button for clear a TextInputEditText
            textValue.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if(event.getAction() == MotionEvent.ACTION_UP) {
                        final TextView textView = (TextView)v;
                        if(event.getX() >= textView.getWidth() - textView.getCompoundPaddingEnd()) {
                            textView.setText(""); //Clear a view, example: EditText or TextView
                            return true;
                        }
                    }
                    return false;
                }
            });

//单击右图标

editText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final int DRAWABLE_RIGHT = 2;

                if(event.getAction() == MotionEvent.ACTION_UP) {
                    if(event.getRawX() >= (createEventBinding.etAddressLine1.getRight() - createEventBinding.etAddressLine1.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                        // your action here

                        Toast.makeText(getActivity(), "Right icon click", Toast.LENGTH_SHORT).show();

                        return true;
                    }
                }
                return false;
            }
        });