为EditText的可绘制权限设置onClickListner
在我的应用程序中,我有一个EditText
右侧的search图标。 我使用下面给出的代码。
<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" />
我想为分配给EditText
右边的可绘制的search图标图像设置EditText
。 怎么可能?
public class CustomEditText extends EditText { 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. * eg 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; } }
另外创build一个接口
public interface DrawableClickListener { public static enum DrawablePosition { TOP, BOTTOM, LEFT, RIGHT }; public void onClick(DrawablePosition target); }
如果你需要帮助,请发表评论
还要在活动文件中的视图上设置drawableClickListener。
editText.setDrawableClickListener(new DrawableClickListener() { public void onClick(DrawablePosition target) { switch (target) { case LEFT: //Do something here break; default: break; } } });
简单的解决scheme,使用Android已经给出的方法,而不是重新发明wheeeeeeeeeel 🙂
editComment.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { final int DRAWABLE_LEFT = 0; final int DRAWABLE_TOP = 1; final int DRAWABLE_RIGHT = 2; final int DRAWABLE_BOTTOM = 3; if(event.getAction() == MotionEvent.ACTION_UP) { if(event.getRawX() >= (editComment.getRight() - editComment.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) { // your action here return true; } } return false; } });
这已经得到了答复,但我尝试了一种不同的方式,使其更简单。
这个想法是使用在EditText
的右侧放置一个ImageButton
,并有一个负的边距,以便EditText
stream入ImageButton
使其看起来像Button是在EditText
。
<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>
另外,如上所示,如果您不希望其中的文本在ImageButton
上飞行,则可以在EditText
使用类似宽度的paddingRight
。
我在android-studio的布局devise师的帮助下猜测了页边距的大小,在所有的屏幕尺寸上看起来都差不多。 否则,您可以计算ImageButton
的宽度并以编程方式设置边距。
就我所知,您无法访问正确的图像,除非您重写onTouch
事件。 我build议使用RelativeLayout
,一个editText
和一个editText
,并在图像视图上设置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>
请使用下面的技巧:
- 用您的图标创build一个图像button,并将其背景色设置为透明。
- 将图像button放在EditText上
- 实现button的'onclic'k监听器来执行你的function
我知道这是相当古老的,但我最近不得不做一些非常相似的事情,并提出了一个更简单的解决scheme。
它归结为以下几个步骤:
- 创build一个包含EditText和Image的XML布局
- 子类FrameLayout并膨胀XML布局
- 为点击侦听器添加代码以及任何其他想要的行为,而无需担心点击或任何其他杂乱代码的位置。
查看这个post的完整例子: 在EditText中处理drawable上的click事件