为EditText的Drawable右侧设置onClickListener

use*_*071 91 android android-edittext

在我的应用程序中,我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" />
Run Code Online (Sandbox Code Playgroud)

我想设置onClickListener分配给右侧drawable的搜索图标图像EditText.这怎么可能?

AZ_*_*AZ_ 279

简单的解决方案,使用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;
        }
    });
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,它适用于(event.getRawX()+ editComment.getPaddingLeft())<=(editComment.getCompoundDrawables()[DRAWABLE_LEFT] .getBounds().width()+ editComment.getLeft())在哪里编辑我有的文字应用drawable paddng (7认同)
  • getRawX()对我不起作用;所以我使用了getX()并且它有效! (5认同)
  • `ACTION_UP`对我不起作用.我改用了'ACTION_DOWN` (5认同)
  • 为我工作.这是按左图标的代码... if(event.getRawX()<=(editComment.getCompoundDrawables()[DRAWABLE_LEFT] .getBounds().width())) (3认同)
  • @user2273146 如果您的长度为 4,那么您的索引必须为 3。因为长度从 1 开始,所以没有 0 长度,但如果长度为 1,则索引为 0 (2认同)

Har*_*560 98

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.
                 * 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;
    }

}
Run Code Online (Sandbox Code Playgroud)

还使用创建接口

public interface DrawableClickListener {

    public static enum DrawablePosition { TOP, BOTTOM, LEFT, RIGHT };
    public void onClick(DrawablePosition target); 
    }
Run Code Online (Sandbox Code Playgroud)

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

还要在活动文件中的视图上设置drawableClickListener.

editText.setDrawableClickListener(new DrawableClickListener() {


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

            default:
                break;
            }
        }

    });
Run Code Online (Sandbox Code Playgroud)

  • 嗨,我找不到CoreSystemContext.SCALE,所以代码显示错误.我怎么能得到CoreSystemContext.SCALE.请指教. (3认同)
  • 这是可变保持装置密度.使用getResources().getDisplayMetrics().密度代替那个,你可能需要在其他文件中创建静态变量.这将px转换为dp.一个简单的解决方案是删除该变量. (3认同)

Mee*_*etM 30

这已经得到了回答,但我尝试了一种不同的方式来简化它.

这个想法是使用一个ImageButton右边的EditText并且有一个负边距,以便EditText流入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>
Run Code Online (Sandbox Code Playgroud)

此外,如上所示,如果您不希望其中的文本飞过,您可以使用paddingRight类似的宽度.EditTextImageButton

我在android-studio的布局设计师的帮助下猜测了边距大小,它在所有屏幕尺寸上看起来都很相似.否则,您可以计算宽度ImageButton并以编程方式设置边距.

  • Linter会警告您“低效率的布局树,使用复合drawable”,而且代码多于drawableRight =“” ... (2认同)

jee*_*eet 6

您没有获得正确的图像,据我所知,除非你重写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>
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

103943 次

最近记录:

6 年,10 月 前