为 EditText 的可绘制权限设置 onClickListener

在我的应用程序中,我有一个右侧带有搜索图标的 EditText。我使用了下面给出的代码。

 <EditText
android:id="@+id/search"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="4dip"
android:layout_weight="1"
android:background="@drawable/textfield_search1"
android:drawableLeft="@drawable/logo"
android:drawableRight="@drawable/search_icon"
android:hint="Search Anything..."
android:padding="4dip"
android:singleLine="true" />

我想设置 onClickListener的搜索图标图像分配到右边的绘图 这怎么可能?

169685 次浏览

请使用以下技巧:

  • 用图标创建一个图像按钮,并将其背景颜色设置为透明。
  • 将图像按钮放在 EditText 上
  • 实现按钮的‘ oncles’k 侦听器来执行你的函数

据我所知,除非你覆盖 onTouch事件,否则你无法访问正确的图像。我建议使用一个 RelativeLayout,一个 editText和一个 imageView,并在图像视图上设置 OnClickListener如下:

<RelativeLayout
android:id="@+id/rlSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:drawable/edit_text"
android:padding="5dip" >


<EditText
android:id="@+id/txtSearch"
android:layout_width="match_parent"


android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/imgSearch"
android:background="#00000000"
android:ems="10"/>


<ImageView
android:id="@+id/imgSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/btnsearch" />
</RelativeLayout>
public class CustomEditText extends androidx.appcompat.widget.AppCompatEditText {


private Drawable drawableRight;
private Drawable drawableLeft;
private Drawable drawableTop;
private Drawable drawableBottom;


int actionX, actionY;


private DrawableClickListener clickListener;


public CustomEditText (Context context, AttributeSet attrs) {
super(context, attrs);
// this Contructure required when you are using this view in xml
}


public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


protected void onDraw(Canvas canvas) {
super.onDraw(canvas);


}


@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}


@Override
public void setCompoundDrawables(Drawable left, Drawable top,
Drawable right, Drawable bottom) {
if (left != null) {
drawableLeft = left;
}
if (right != null) {
drawableRight = right;
}
if (top != null) {
drawableTop = top;
}
if (bottom != null) {
drawableBottom = bottom;
}
super.setCompoundDrawables(left, top, right, bottom);
}


@Override
public boolean onTouchEvent(MotionEvent event) {
Rect bounds;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
actionX = (int) event.getX();
actionY = (int) event.getY();
if (drawableBottom != null
&& drawableBottom.getBounds().contains(actionX, actionY)) {
clickListener.onClick(DrawablePosition.BOTTOM);
return super.onTouchEvent(event);
}


if (drawableTop != null
&& drawableTop.getBounds().contains(actionX, actionY)) {
clickListener.onClick(DrawablePosition.TOP);
return super.onTouchEvent(event);
}


// this works for left since container shares 0,0 origin with bounds
if (drawableLeft != null) {
bounds = null;
bounds = drawableLeft.getBounds();


int x, y;
int extraTapArea = (int) (13 * getResources().getDisplayMetrics().density  + 0.5);


x = actionX;
y = actionY;


if (!bounds.contains(actionX, actionY)) {
/** Gives the +20 area for tapping. */
x = (int) (actionX - extraTapArea);
y = (int) (actionY - extraTapArea);


if (x <= 0)
x = actionX;
if (y <= 0)
y = actionY;


/** Creates square from the smallest value */
if (x < y) {
y = x;
}
}


if (bounds.contains(x, y) && clickListener != null) {
clickListener
.onClick(DrawableClickListener.DrawablePosition.LEFT);
event.setAction(MotionEvent.ACTION_CANCEL);
return false;


}
}


if (drawableRight != null) {


bounds = null;
bounds = drawableRight.getBounds();


int x, y;
int extraTapArea = 13;


/**
* IF USER CLICKS JUST OUT SIDE THE RECTANGLE OF THE DRAWABLE
* THAN ADD X AND SUBTRACT THE Y WITH SOME VALUE SO THAT AFTER
* CALCULATING X AND Y CO-ORDINATE LIES INTO THE DRAWBABLE
* BOUND. - this process help to increase the tappable area of
* the rectangle.
*/
x = (int) (actionX + extraTapArea);
y = (int) (actionY - extraTapArea);


/**Since this is right drawable subtract the value of x from the width
* of view. so that width - tappedarea will result in x co-ordinate in drawable bound.
*/
x = getWidth() - x;
                

/*x can be negative if user taps at x co-ordinate just near the width.
* e.g views width = 300 and user taps 290. Then as per previous calculation
* 290 + 13 = 303. So subtract X from getWidth() will result in negative value.
* So to avoid this add the value previous added when x goes negative.
*/
                 

if(x <= 0){
x += extraTapArea;
}
                

/* If result after calculating for extra tappable area is negative.
* assign the original value so that after subtracting
* extratapping area value doesn't go into negative value.
*/
                 

if (y <= 0)
y = actionY;


/**If drawble bounds contains the x and y points then move ahead.*/
if (bounds.contains(x, y) && clickListener != null) {
clickListener
.onClick(DrawableClickListener.DrawablePosition.RIGHT);
event.setAction(MotionEvent.ACTION_CANCEL);
return false;
}
return super.onTouchEvent(event);
}


}
return super.onTouchEvent(event);
}


@Override
protected void finalize() throws Throwable {
drawableRight = null;
drawableBottom = null;
drawableLeft = null;
drawableTop = null;
super.finalize();
}


public void setDrawableClickListener(DrawableClickListener listener) {
this.clickListener = listener;
}


}

创建接口

public interface DrawableClickListener {


public static enum DrawablePosition { TOP, BOTTOM, LEFT, RIGHT };
public void onClick(DrawablePosition target);
}

如果你需要任何帮助,请评论

还要在活动文件中的视图上设置 draableClickListener。

editText.setDrawableClickListener(new DrawableClickListener() {
        

         

public void onClick(DrawablePosition target) {
switch (target) {
case LEFT:
//Do something here
break;


default:
break;
}
}
        

});

我知道这是相当古老的,但我最近不得不做一些非常类似的事情,并提出了一个更简单的解决方案。

它可以归结为以下几个步骤:

  1. 创建包含 EditText 和 Image 的 XML 布局
  2. 子类 FrameLayout 并膨胀 XML 布局
  3. 添加点击监听器的代码和任何其他您想要的行为... 而不必担心点击的位置或任何其他凌乱的代码。

完整的例子见这篇文章: 处理 EditText 中可绘制内容上的单击事件

这个问题已经得到了回答,但我尝试了一种不同的方法,使它变得更简单。

这个想法是使用一个 ImageButton在右边的 EditText和有负边距,使 EditText流入 ImageButton使它看起来像按钮是在 EditText

enter image description here

    <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/editText"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Enter Pin"
android:singleLine="true"
android:textSize="25sp"
android:paddingRight="60dp"
/>
<ImageButton
android:id="@+id/pastePin"
android:layout_marginLeft="-60dp"
style="?android:buttonBarButtonStyle"
android:paddingBottom="5dp"
android:src="@drawable/ic_action_paste"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

此外,如上所示,你可以使用类似的宽度在 EditTextpaddingRight,如果你不希望它的文字飞越 ImageButton

我在 android 工作室的布局设计师的帮助下猜测了边距的大小,所有的屏幕尺寸看起来都差不多。或者,您可以计算 ImageButton的宽度并以编程方式设置边距。