การจัดการเหตุการณ์คลิกใน drawable ภายใน EditText


239

ฉันได้เพิ่มรูปภาพด้านขวาของข้อความใน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เมื่อมีการคลิกภาพที่ฝังอยู่ ฉันจะทำสิ่งนี้ได้อย่างไร


สำเนาซ้ำที่เป็นไปได้ของstackoverflow.com/questions/13135447/ …
Hardik4560

คำตอบ:


358

จริงๆแล้วคุณไม่จำเป็นต้องขยายชั้นเรียนใด ๆ สมมติว่าฉันมี EditText editComment ด้วย drawableRight

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;
    }
});

เรา getRawX()เพราะเราต้องการรับตำแหน่งที่แท้จริงของการสัมผัสบนหน้าจอไม่สัมพันธ์กับผู้ปกครอง

หากต้องการรับด้านซ้ายให้คลิก

if(event.getRawX() <= (editComment.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width())) 

2
@ user2848783 วิธีการตั้งค่านี้ใน drawable ซ้ายของฉัน
Qadir Hussain

10
ทำงานหลังจากเปลี่ยนevent.getRawX()แทนevent.getX()@AngeloS
Pratik Butani

4
One note: แทนที่ "return false;" ไปที่ "return true;" มิฉะนั้นหลังจาก ACTION_DOWN -> ACTION_UP จะไม่ถูกไล่ออก
tomurka

9
หากคุณเพิ่มการขยายคุณจำเป็นต้องนับว่ารวมถึงการgetRight()ได้รับสิทธิ์ของ TextView ซึ่งจะไม่ถูกต้องของ drawable หากมีการขยาย การเพิ่ม- editComment.getPaddingRight()ในส่วนท้ายของใบแจ้งยอดของคุณน่าifจะใช้ได้
kassim

21
สิ่งนี้ใช้ไม่ได้หากพาเรนต์ของ EditText ไม่ตรงกับด้านซ้ายของหน้าจอ คุณควรใช้ event.getX () แทน event.getRawX () และใช้ editText.getWidth () แทน editText.getRight ()
Fletcher Johns

85

ดีมากขอบคุณทุกคนที่มีส่วนร่วมในการอภิปรายนี้ ดังนั้นหากคุณไม่ต้องการที่จะจัดการกับความไม่สะดวกในการขยายชั้นเรียนคุณสามารถทำสิ่งต่อไปนี้

this.keyword = (AutoCompleteTextView) findViewById(R.id.search);
this.keyword.setOnTouchListener(new RightDrawableOnTouchListener(keyword) {
        @Override
        public boolean onDrawableTouch(final MotionEvent event) {
            return onClickSearch(keyword,event);
        }
    });

private boolean onClickSearch(final View view, MotionEvent event) {
    // do something
    event.setAction(MotionEvent.ACTION_CANCEL);
    return false;
}

และนี่คือการนำผู้ฟังไปใช้งานโดยอาศัยคำตอบของ @ Mark

public abstract class RightDrawableOnTouchListener implements OnTouchListener {
    Drawable drawable;
    private int fuzz = 10;

    /**
     * @param keyword
     */
    public RightDrawableOnTouchListener(TextView view) {
        super();
        final Drawable[] drawables = view.getCompoundDrawables();
        if (drawables != null && drawables.length == 4)
            this.drawable = drawables[2];
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent)
     */
    @Override
    public boolean onTouch(final View v, final MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN && drawable != null) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();
            final Rect bounds = drawable.getBounds();
            if (x >= (v.getRight() - bounds.width() - fuzz) && x <= (v.getRight() - v.getPaddingRight() + fuzz)
                    && y >= (v.getPaddingTop() - fuzz) && y <= (v.getHeight() - v.getPaddingBottom()) + fuzz) {
                return onDrawableTouch(event);
            }
        }
        return false;
    }

    public abstract boolean onDrawableTouch(final MotionEvent event);

}

3
คุณควรเพิ่ม v.getLeft () ลงใน x และ v.getTop () ถึง y เพื่อรับตำแหน่งที่ถูกต้อง
André

3
จริงๆคุณควรเปลี่ยนโดยv.getRight() v.getWidth()
Speedy

2
โปรดทราบว่าปัจจัยฝอยของคุณควรปรับขนาดด้วย DPI, 10px ใน ldpi เป็นสิ่งที่แตกต่างอย่างสิ้นเชิงจาก 10px ใน xxhdpi
RaB

4
Fuzz คืออะไร กรุณาชี้แจง
ЮрійМазуревич

1
ดูเหมือนว่าfuzzทำให้พื้นที่แท็บมีขนาดใหญ่ขึ้นได้อย่างมีประสิทธิภาพทำให้ง่ายต่อการแตะขนาดเล็ก
บ้านจีโอเอ็นจิเนียริ่ง

28

พิจารณาดังต่อไปนี้ มันไม่ใช่ทางออกที่หรูหราที่สุด แต่ใช้งานได้ฉันเพิ่งทดสอบ

  1. สร้างEditTextคลาสที่กำหนดเองCustomEditText.java:

    import android.content.Context;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.widget.EditText;
    
    public class CustomEditText extends EditText
    {
      private Drawable dRight;
      private Rect rBounds;
    
      public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
      }
      public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
      public CustomEditText(Context context) {
        super(context);
      }
    
      @Override
      public void setCompoundDrawables(Drawable left, Drawable top,
          Drawable right, Drawable bottom)
      {
        if(right !=null)
        {
          dRight = right;
        }
        super.setCompoundDrawables(left, top, right, bottom);
      }
    
      @Override
      public boolean onTouchEvent(MotionEvent event)
      {
    
        if(event.getAction() == MotionEvent.ACTION_UP && dRight!=null)
        {
          rBounds = dRight.getBounds();
          final int x = (int)event.getX();
          final int y = (int)event.getY();
          //System.out.println("x:/y: "+x+"/"+y);
          //System.out.println("bounds: "+bounds.left+"/"+bounds.right+"/"+bounds.top+"/"+bounds.bottom);
          //check to make sure the touch event was within the bounds of the drawable
          if(x>=(this.getRight()-rBounds.width()) && x<=(this.getRight()-this.getPaddingRight())
              && y>=this.getPaddingTop() && y<=(this.getHeight()-this.getPaddingBottom()))
          {
            //System.out.println("touch");
            this.setText("");
            event.setAction(MotionEvent.ACTION_CANCEL);//use this to prevent the keyboard from coming up
          }
        }
        return super.onTouchEvent(event);
      }
    
      @Override
      protected void finalize() throws Throwable
      {
        dRight = null;
        rBounds = null;
        super.finalize();
      }
    }
  2. เปลี่ยนเค้าโครง XML com.exampleของคุณเป็น(ซึ่งเป็นชื่อแพคเกจโครงการจริงของคุณ):

    <com.example.CustomEditText
        android:id="@+id/txtsearch"android:layout_gravity="center_vertical"
        android:background="@layout/shape"
        android:hint="Enter place,city,state"
        android:drawableRight="@drawable/cross" 
    />
  3. ในที่สุดเพิ่มสิ่งนี้ (หรือบางอย่างที่คล้ายกัน) ให้กับกิจกรรมของคุณ:

    
    CustomEditText et = (CustomEditText) this.findViewById(R.id.txtsearch);
    

ฉันอาจจะออกไปเล็กน้อยกับการคำนวณขอบเขตการสัมผัสสำหรับ drawable ซ้อน แต่คุณได้รับความคิด

ฉันหวังว่านี่จะช่วยได้.


อันที่จริงผมเคยได้ยินว่าการปรับเปลี่ยน MotionEvent คือการปฏิบัติท้อแท้นำไปสู่พฤติกรรมที่ไม่ได้กำหนดว่ามีแนวโน้มว่าจะทำลายบนแพลตฟอร์มที่แตกต่างกันดังนั้นบางทีอาจจะเป็นทางออกที่ดีกว่าอาจจะstackoverflow.com/a/6235602
Giulio Piancastelli

@RyanM ผมใช้แทนTextView EditTextฉันเอารหัสและถ้าฉันคลิกที่TextView(ไม่ใช่ไอคอน แต่ในพื้นที่ใด ๆ บนTextView) วิธีการที่onTouchEvent(MotionEvent event)เรียกว่า ดังนั้นฉันสามารถใช้งานได้OnClickListenerตามปกติTextViewโดยไม่มีคลาสเพิ่มเติมใด ๆ เช่นCustomEditText
Maksim Dmitriev

@RyanM แทนที่จะใช้this.getRight()-rBounds.width()ทำไมไม่ใช้this.getMeasuredWidth() - this.getCompoundPaddingRight()? มันจะไม่ดูแลช่องว่างภายในของ drawable และกำจัดขอบเขตของ drawable หรือไม่?
Vino

@RyanM วิธีการเปลี่ยนภาพเมื่อกดปุ่มกากบาทคลิกเหตุการณ์?
Qadir Hussain

รุ่นที่กำหนดเองของEditTextไม่สนับสนุนการย้อมสีวิดเจ็ตที่เหมาะสมเมื่อใช้ appcompat บนอุปกรณ์ก่อนอมยิ้ม ใช้AppCompatEditTextเป็นคลาสพาเรนต์ของ EditText ที่กำหนดเองของคุณ
Tomask

24

ฉันสร้างคลาสนามธรรมที่มีประโยชน์DrawableClickListenerซึ่งใช้OnTouchListener OnTouchListener

นอกจากคลาสDrawableClickListenerแล้วฉันยังสร้างคลาสนามธรรมเพิ่มเติมอีก 4 คลาสซึ่งขยายคลาสDrawableClickListenerและจัดการการคลิกพื้นที่ drawable สำหรับควอดเรนที่ถูกต้อง

  • LeftDrawableClickListener
  • TopDrawableClickListener
  • RightDrawableClickListener
  • BottomDrawableClickListener

ชี้ไปที่ต้องพิจารณา

สิ่งหนึ่งที่ควรพิจารณาคือรูปภาพจะไม่ถูกปรับขนาดถ้าทำด้วยวิธีนี้ ดังนั้นภาพจะต้องถูกปรับขนาดอย่างถูกต้องก่อนที่จะใส่เข้าไปในres / drawableโฟลเดอร์

หากคุณกำหนดLinearLayoutที่มีImageViewและTextViewจะง่ายกว่ามากในการจัดการขนาดของภาพที่จะแสดง


activity_my.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/myTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="replace this with a variable"
        android:textSize="30sp"
        android:drawableLeft="@drawable/my_left_image"
        android:drawableRight="@drawable/my_right_image"
        android:drawablePadding="9dp" />

</RelativeLayout>

MyActivity.java

package com.company.project.core;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MyActivity extends Activity
{

    @Override
    protected void onCreate( Bundle savedInstanceState )
    {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_my );

        final TextView myTextView = (TextView) this.findViewById( R.id.myTextView );
        myTextView.setOnTouchListener( new DrawableClickListener.LeftDrawableClickListener(myTextView)
        {
            @Override
            public boolean onDrawableClick()
            {
                // TODO : insert code to perform on clicking of the LEFT drawable image...

                return true;
            }
        } );
        myTextView.setOnTouchListener( new DrawableClickListener.RightDrawableClickListener(myTextView)
        {
            @Override
            public boolean onDrawableClick()
            {
                // TODO : insert code to perform on clicking of the RIGHT drawable image...

                return true;
            }
        } );
    }

}

DrawableClickListener.java

package com.company.project.core;

import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.TextView;

/**
 * This class can be used to define a listener for a compound drawable.
 * 
 * @author Matthew Weiler
 * */
public abstract class DrawableClickListener implements OnTouchListener
{

    /* PUBLIC CONSTANTS */
    /**
     * This represents the left drawable.
     * */
    public static final int DRAWABLE_INDEX_LEFT = 0;
    /**
     * This represents the top drawable.
     * */
    public static final int DRAWABLE_INDEX_TOP = 1;
    /**
     * This represents the right drawable.
     * */
    public static final int DRAWABLE_INDEX_RIGHT = 2;
    /**
     * This represents the bottom drawable.
     * */
    public static final int DRAWABLE_INDEX_BOTTOM = 3;
    /**
     * This stores the default value to be used for the
     * {@link DrawableClickListener#fuzz}.
     * */
    public static final int DEFAULT_FUZZ = 10;

    /* PRIVATE VARIABLES */
    /**
     * This stores the number of pixels of &quot;fuzz&quot; that should be
     * included to account for the size of a finger.
     * */
    private final int fuzz;
    /**
     * This will store a reference to the {@link Drawable}.
     * */
    private Drawable drawable = null;

    /* CONSTRUCTORS */
    /**
     * This will create a new instance of a {@link DrawableClickListener}
     * object.
     * 
     * @param view
     *            The {@link TextView} that this {@link DrawableClickListener}
     *            is associated with.
     * @param drawableIndex
     *            The index of the drawable that this
     *            {@link DrawableClickListener} pertains to.
     *            <br />
     *            <i>use one of the values:
     *            <b>DrawableOnTouchListener.DRAWABLE_INDEX_*</b></i>
     */
    public DrawableClickListener( final TextView view, final int drawableIndex )
    {
        this( view, drawableIndex, DrawableClickListener.DEFAULT_FUZZ );
    }

    /**
     * This will create a new instance of a {@link DrawableClickListener}
     * object.
     * 
     * @param view
     *            The {@link TextView} that this {@link DrawableClickListener}
     *            is associated with.
     * @param drawableIndex
     *            The index of the drawable that this
     *            {@link DrawableClickListener} pertains to.
     *            <br />
     *            <i>use one of the values:
     *            <b>DrawableOnTouchListener.DRAWABLE_INDEX_*</b></i>
     * @param fuzzOverride
     *            The number of pixels of &quot;fuzz&quot; that should be
     *            included to account for the size of a finger.
     */
    public DrawableClickListener( final TextView view, final int drawableIndex, final int fuzz )
    {
        super();
        this.fuzz = fuzz;
        final Drawable[] drawables = view.getCompoundDrawables();
        if ( drawables != null && drawables.length == 4 )
        {
            this.drawable = drawables[drawableIndex];
        }
    }

    /* OVERRIDDEN PUBLIC METHODS */
    @Override
    public boolean onTouch( final View v, final MotionEvent event )
    {
        if ( event.getAction() == MotionEvent.ACTION_DOWN && drawable != null )
        {
            final int x = (int) event.getX();
            final int y = (int) event.getY();
            final Rect bounds = drawable.getBounds();
            if ( this.isClickOnDrawable( x, y, v, bounds, this.fuzz ) )
            {
                return this.onDrawableClick();
            }
        }
        return false;
    }

    /* PUBLIC METHODS */
    /**
     * 
     * */
    public abstract boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz );

    /**
     * This method will be fired when the drawable is touched/clicked.
     * 
     * @return
     *         <code>true</code> if the listener has consumed the event;
     *         <code>false</code> otherwise.
     * */
    public abstract boolean onDrawableClick();

    /* PUBLIC CLASSES */
    /**
     * This class can be used to define a listener for a <b>LEFT</b> compound
     * drawable.
     * */
    public static abstract class LeftDrawableClickListener extends DrawableClickListener
    {

        /* CONSTRUCTORS */
        /**
         * This will create a new instance of a
         * {@link LeftDrawableClickListener} object.
         * 
         * @param view
         *            The {@link TextView} that this
         *            {@link LeftDrawableClickListener} is associated with.
         */
        public LeftDrawableClickListener( final TextView view )
        {
            super( view, DrawableClickListener.DRAWABLE_INDEX_LEFT );
        }

        /**
         * This will create a new instance of a
         * {@link LeftDrawableClickListener} object.
         * 
         * @param view
         *            The {@link TextView} that this
         *            {@link LeftDrawableClickListener} is associated with.
         * @param fuzzOverride
         *            The number of pixels of &quot;fuzz&quot; that should be
         *            included to account for the size of a finger.
         */
        public LeftDrawableClickListener( final TextView view, final int fuzz )
        {
            super( view, DrawableClickListener.DRAWABLE_INDEX_LEFT, fuzz );
        }

        /* PUBLIC METHODS */
        public boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz )
        {
            if ( x >= ( view.getPaddingLeft() - fuzz ) )
            {
                if ( x <= ( view.getPaddingLeft() + drawableBounds.width() + fuzz ) )
                {
                    if ( y >= ( view.getPaddingTop() - fuzz ) )
                    {
                        if ( y <= ( view.getHeight() - view.getPaddingBottom() + fuzz ) )
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

    }

    /**
     * This class can be used to define a listener for a <b>TOP</b> compound
     * drawable.
     * */
    public static abstract class TopDrawableClickListener extends DrawableClickListener
    {

        /* CONSTRUCTORS */
        /**
         * This will create a new instance of a {@link TopDrawableClickListener}
         * object.
         * 
         * @param view
         *            The {@link TextView} that this
         *            {@link TopDrawableClickListener} is associated with.
         */
        public TopDrawableClickListener( final TextView view )
        {
            super( view, DrawableClickListener.DRAWABLE_INDEX_TOP );
        }

        /**
         * This will create a new instance of a {@link TopDrawableClickListener}
         * object.
         * 
         * @param view
         *            The {@link TextView} that this
         *            {@link TopDrawableClickListener} is associated with.
         * @param fuzzOverride
         *            The number of pixels of &quot;fuzz&quot; that should be
         *            included to account for the size of a finger.
         */
        public TopDrawableClickListener( final TextView view, final int fuzz )
        {
            super( view, DrawableClickListener.DRAWABLE_INDEX_TOP, fuzz );
        }

        /* PUBLIC METHODS */
        public boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz )
        {
            if ( x >= ( view.getPaddingLeft() - fuzz ) )
            {
                if ( x <= ( view.getWidth() - view.getPaddingRight() + fuzz ) )
                {
                    if ( y >= ( view.getPaddingTop() - fuzz ) )
                    {
                        if ( y <= ( view.getPaddingTop() + drawableBounds.height() + fuzz ) )
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

    }

    /**
     * This class can be used to define a listener for a <b>RIGHT</b> compound
     * drawable.
     * */
    public static abstract class RightDrawableClickListener extends DrawableClickListener
    {

        /* CONSTRUCTORS */
        /**
         * This will create a new instance of a
         * {@link RightDrawableClickListener} object.
         * 
         * @param view
         *            The {@link TextView} that this
         *            {@link RightDrawableClickListener} is associated with.
         */
        public RightDrawableClickListener( final TextView view )
        {
            super( view, DrawableClickListener.DRAWABLE_INDEX_RIGHT );
        }

        /**
         * This will create a new instance of a
         * {@link RightDrawableClickListener} object.
         * 
         * @param view
         *            The {@link TextView} that this
         *            {@link RightDrawableClickListener} is associated with.
         * @param fuzzOverride
         *            The number of pixels of &quot;fuzz&quot; that should be
         *            included to account for the size of a finger.
         */
        public RightDrawableClickListener( final TextView view, final int fuzz )
        {
            super( view, DrawableClickListener.DRAWABLE_INDEX_RIGHT, fuzz );
        }

        /* PUBLIC METHODS */
        public boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz )
        {
            if ( x >= ( view.getWidth() - view.getPaddingRight() - drawableBounds.width() - fuzz ) )
            {
                if ( x <= ( view.getWidth() - view.getPaddingRight() + fuzz ) )
                {
                    if ( y >= ( view.getPaddingTop() - fuzz ) )
                    {
                        if ( y <= ( view.getHeight() - view.getPaddingBottom() + fuzz ) )
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

    }

    /**
     * This class can be used to define a listener for a <b>BOTTOM</b> compound
     * drawable.
     * */
    public static abstract class BottomDrawableClickListener extends DrawableClickListener
    {

        /* CONSTRUCTORS */
        /**
         * This will create a new instance of a
         * {@link BottomDrawableClickListener} object.
         * 
         * @param view
         *            The {@link TextView} that this
         *            {@link BottomDrawableClickListener} is associated with.
         */
        public BottomDrawableClickListener( final TextView view )
        {
            super( view, DrawableClickListener.DRAWABLE_INDEX_BOTTOM );
        }

        /**
         * This will create a new instance of a
         * {@link BottomDrawableClickListener} object.
         * 
         * @param view
         *            The {@link TextView} that this
         *            {@link BottomDrawableClickListener} is associated with.
         * @param fuzzOverride
         *            The number of pixels of &quot;fuzz&quot; that should be
         *            included to account for the size of a finger.
         */
        public BottomDrawableClickListener( final TextView view, final int fuzz )
        {
            super( view, DrawableClickListener.DRAWABLE_INDEX_BOTTOM, fuzz );
        }

        /* PUBLIC METHODS */
        public boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz )
        {
            if ( x >= ( view.getPaddingLeft() - fuzz ) )
            {
                if ( x <= ( view.getWidth() - view.getPaddingRight() + fuzz ) )
                {
                    if ( y >= ( view.getHeight() - view.getPaddingBottom() - drawableBounds.height() - fuzz ) )
                    {
                        if ( y <= ( view.getHeight() - view.getPaddingBottom() + fuzz ) )
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

    }

}

14

มันง่ายมาก ให้บอกว่าคุณมี drawable ทางด้านซ้ายของ EditText 'txtsearch' ของคุณ ต่อไปนี้จะทำเคล็ดลับ

EditText txtsearch = (EditText) findViewById(R.id.txtsearch);
txtsearch.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_UP) {
            if(event.getRawX() <= txtsearch.getTotalPaddingLeft()) {
                // your action for drawable click event

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

ถ้าคุณต้องการให้ drawable ถูกต้องให้เปลี่ยนคำสั่ง if เป็น:

if(event.getRawX() >= txtsearch.getRight() - txtsearch.getTotalPaddingRight())

ในทำนองเดียวกันคุณสามารถทำมันได้สำหรับ drawable ผสมทั้งหมด

txtsearch.getTotalPaddingTop()
txtsearch.getTotalPaddingBottom()

การเรียกเมธอดนี้ส่งคืนการ padding ทั้งหมดที่ด้านนั้นรวมถึง drawable ใด ๆ คุณสามารถใช้สิ่งนี้ได้แม้กับ TextView ปุ่ม ฯลฯ

คลิกที่นี่เพื่ออ้างอิงจากเว็บไซต์นักพัฒนา android


1
ฉันคิดว่านี่เป็นคำตอบที่ดียกเว้นส่วนที่ความจริงถูกส่งคืนทุกที่ ฉันขอแนะนำให้ส่งคืนจริงเมื่อเหตุการณ์จำเป็นต้องใช้ (ท่าทางสัมผัสเกิดขึ้นในพื้นที่ที่เหมาะสม)
Bianca Daniciuc

12

ฉันคิดว่ามันง่ายกว่าถ้าเราใช้ลูกเล่นบางอย่าง :)

  1. สร้างปุ่มรูปภาพพร้อมไอคอนและตั้งค่าสีพื้นหลังให้โปร่งใสแบบโปร่งใส
  2. วางปุ่มรูปภาพบน EditText และจาก coz ทางด้านขวามือ
  3. ใช้ฟังของปุ่มเพื่อดำเนินการฟังก์ชั่นของคุณ

เสร็จสิ้น


1
ใช้RelativeLayoutเพื่อให้ได้ตำแหน่งที่เหมาะสมดูเหมือนว่ามีความซับซ้อนน้อยกว่าโซลูชันอื่น ๆ และใช้รหัสน้อยกว่าในการบำรุงรักษา
C0D3LIC1OU5

12

การใช้งานครั้งล่าสุดนั้นcontains(x,y)จะไม่ทำงานโดยตรงกับผลลัพธ์ของgetBounds()(ยกเว้นโดยบังเอิญเมื่อใช้ drawable "left") getBoundsวิธีการเดียวที่มีRectการกำหนดจุดของรายการ drawable ปกติที่มีต้นกำเนิดที่ 0,0 - ดังนั้นคุณจริงต้องทำคณิตศาสตร์ของโพสต์เดิมที่จะพบว่าการคลิกอยู่ในพื้นที่ของ drawable ในบริบทของ มีขนาดของ EditText แต่เปลี่ยนเป็นด้านบนขวาซ้าย ฯลฯ หรือคุณสามารถอธิบายRectว่ามีพิกัดจริง ๆ แล้วสัมพันธ์กับตำแหน่งในEditTextคอนเทนเนอร์และการใช้งานcontains()แม้ว่าในท้ายที่สุดคุณจะใช้คณิตศาสตร์ตัวเดียวกัน

เมื่อรวมทั้งสองอย่างเข้าด้วยกันจะช่วยให้คุณได้โซลูชันที่สมบูรณ์ฉันเพียงเพิ่มแอททริบิวต์อินสแตนซ์consumesEventที่ช่วยให้ผู้ใช้ API ตัดสินใจได้ว่าเหตุการณ์การคลิกควรถูกส่งผ่านหรือไม่โดยใช้ผลการตั้งค่าACTION_CANCELหรือไม่

นอกจากนี้ผมไม่สามารถดูว่าทำไมboundsและactionX,actionYมีค่าเช่นแอตทริบิวต์มากกว่าแค่ท้องถิ่นในกอง

นี่คือส่วนตัดจากการนำไปใช้ตามที่กล่าวไว้ข้างต้น จะแก้ไขปัญหาที่ใช้เหตุการณ์ที่คุณต้องส่งกลับเท็จอย่างถูกต้อง เพิ่มปัจจัย "ฝอย" เป็น ในกรณีที่ฉันใช้ไอคอนควบคุมด้วยเสียงในEditTextเขตข้อมูลฉันพบว่ามันยากที่จะคลิกดังนั้นฝอยจึงเพิ่มขอบเขตที่มีประสิทธิภาพซึ่งถือว่าเป็นการคลิกที่วาดได้ สำหรับฉัน15ทำงานได้ดี ฉันต้องการเพียงเท่านั้นdrawableRightดังนั้นฉันจึงไม่ได้เสียบคณิตศาสตร์ในที่อื่นเพื่อประหยัดพื้นที่ แต่คุณเห็นความคิด

package com.example.android;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.EditText;
import android.graphics.Rect;

import com.example.android.DrawableClickListener;

public class ClickableButtonEditText extends EditText {
  public static final String LOG_TAG = "ClickableButtonEditText";

  private Drawable drawableRight;
  private Drawable drawableLeft;
  private Drawable drawableTop;
  private Drawable drawableBottom;
  private boolean consumeEvent = false;
  private int fuzz = 0;

  private DrawableClickListener clickListener;

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

  public ClickableButtonEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public ClickableButtonEditText(Context context) {
    super(context);
  }

  public void consumeEvent() {
    this.setConsumeEvent(true);
  }

  public void setConsumeEvent(boolean b) {
    this.consumeEvent = b;
  }

  public void setFuzz(int z) {
    this.fuzz = z;
  }

  public int getFuzz() {
    return fuzz;
  }

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

    if (left != null) {
      drawableLeft = left;
    }
    super.setCompoundDrawables(left, top, right, bottom);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      int x, y;
      Rect bounds;
      x = (int) event.getX();
      y = (int) event.getY();
      // this works for left since container shares 0,0 origin with bounds
      if (drawableLeft != null) {
        bounds = drawableLeft.getBounds();
        if (bounds.contains(x - fuzz, y - fuzz)) {
          clickListener.onClick(DrawableClickListener.DrawablePosition.LEFT);
          if (consumeEvent) {
            event.setAction(MotionEvent.ACTION_CANCEL);
            return false;
          }
        }
      } else if (drawableRight != null) {
        bounds = drawableRight.getBounds();
        if (x >= (this.getRight() - bounds.width() - fuzz) && x <= (this.getRight() - this.getPaddingRight() + fuzz) 
              && y >= (this.getPaddingTop() - fuzz) && y <= (this.getHeight() - this.getPaddingBottom()) + fuzz) {

          clickListener.onClick(DrawableClickListener.DrawablePosition.RIGHT);
          if (consumeEvent) {
            event.setAction(MotionEvent.ACTION_CANCEL);
            return false;
          }
        }
      } else if (drawableTop != null) {
        // not impl reader exercise :)
      } else if (drawableBottom != null) {
        // not impl reader exercise :)
      }
    }

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

8

ขยายความคิดโดย RyanM ฉันได้สร้างเวอร์ชันที่ยืดหยุ่นมากขึ้นซึ่งรองรับประเภท drawable ทั้งหมด (บน, ล่าง, ซ้าย, ขวา) แม้ว่าโค้ดด้านล่างจะขยาย TextView แต่การปรับใช้สำหรับ EditText นั้นเป็นเพียงกรณีของการสลับ "extends TextView" ด้วย "extends EditText" การสร้างอินสแตนซ์ของวิดเจ็ตจาก XML เหมือนกับในตัวอย่างของ RyanM ให้แยกชื่อวิดเจ็ต


import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

import com.example.DrawableClickListener.DrawablePosition;

public class ButtonTextView extends TextView {

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

private int     actionX, actionY;

private DrawableClickListener clickListener;

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

public ButtonTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public ButtonTextView(Context context) {
    super(context);
}

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

    if (left != null) {
        drawableLeft = left;
    }

    if (top != null) {
        drawableTop = top;
    }

    if (bottom != null) {
        drawableBottom = bottom;
    }

    super.setCompoundDrawables(left, top, right, bottom);
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    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);
        }

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

        if (drawableRight != null && drawableRight.getBounds().contains(actionX, actionY)) {
            clickListener.onClick(DrawablePosition.RIGHT);
            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;
}}

DrawableClickListener นั้นเรียบง่ายเช่นนี้:

public interface DrawableClickListener {

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

จากนั้นการใช้งานจริง:

class example implements DrawableClickListener {
public void onClick(DrawablePosition target) {
    switch (target) {
        case LEFT:
            doSomethingA();
            break;

        case RIGHT:
            doSomethingB();
            break;

        case BOTTOM:
            doSomethingC();
            break;

        case TOP:
            doSomethingD();
            break;

        default:
            break;
    }
}}

ps: หากคุณไม่ได้ตั้งค่าผู้ฟังการแตะ TextView จะทำให้ NullPointerException คุณอาจต้องการเพิ่มความหวาดระแวงในรหัส


ดูเหมือนว่ารหัสของคุณไม่ทำงานฉันเพิ่งผ่านการทดสอบและไม่มีอะไรเกิดขึ้นเมื่อฉันสัมผัสกับ drawable
Thiago

8

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()
    }

7

มันทำงานให้ฉัน

mEditTextSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if(s.length()>0){
                mEditTextSearch.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(android.R.drawable.ic_delete), null);
            }else{
                mEditTextSearch.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.drawable.abc_ic_search), null);
            }
        }
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }
        @Override
        public void afterTextChanged(Editable s) {
        }
    });
    mEditTextSearch.setOnTouchListener(new OnTouchListener() {
        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_UP) {
                if(mEditTextSearch.getCompoundDrawables()[2]!=null){
                    if(event.getX() >= (mEditTextSearch.getRight()- mEditTextSearch.getLeft() - mEditTextSearch.getCompoundDrawables()[2].getBounds().width())) {
                        mEditTextSearch.setText("");
                    }
                }
            }
            return false;
        }
    });

จำเป็นต้องลบการแพ็ดด้านขวาหากมีสำหรับการแก้ไขข้อความเมื่อพิจารณาการเริ่มต้นของสี่เหลี่ยมผืนผ้าที่มีผลกระทบ
farid_z

4

ฉันรู้ว่ามันค่อนข้างเก่า แต่เมื่อเร็ว ๆ นี้ฉันต้องทำสิ่งที่คล้ายกัน ... หลังจากเห็นว่ามันยากขนาดไหนฉันจึงได้วิธีแก้ปัญหาที่ง่ายกว่านี้มากขึ้น:

  1. สร้างเค้าโครง XML ที่มี EditText และ Image
  2. Subclass FrameLayout และขยายเค้าโครง XML
  3. เพิ่มรหัสสำหรับฟังคลิกและพฤติกรรมอื่น ๆ ที่คุณต้องการ

ในกรณีของฉันฉันต้องการ EditText ที่มีความสามารถในการล้างข้อความด้วยปุ่ม ฉันต้องการให้ดูเหมือนกับ SearchView แต่ด้วยเหตุผลหลายประการฉันไม่ต้องการใช้คลาสนั้น ตัวอย่างด้านล่างแสดงวิธีการทำสิ่งนี้ให้สำเร็จ แม้ว่ามันจะไม่ได้เกี่ยวข้องกับการเปลี่ยนโฟกัส แต่หลักการก็เหมือนกันและฉันคิดว่ามันจะมีประโยชน์มากกว่าในการโพสต์รหัสการทำงานจริงมากกว่าที่จะใส่ตัวอย่างที่อาจไม่ทำงานอย่างที่ฉันต้องการ:

นี่คือเค้าโครงของฉัน: clearable_edit_text.xml

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

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

    <!-- NOTE: Visibility cannot be set to "gone" or the padding won't get set properly in code -->
    <ImageButton
        android:id="@+id/edit_text_clear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|center_vertical"
        android:background="@drawable/ic_cancel_x"
        android:visibility="invisible"/>
</merge>

และนี่คือคลาสที่ขยายเค้าโครงนั้น: ClearableEditText.java

public class ClearableEditText extends FrameLayout {
    private boolean mPaddingSet = false;

    /**
     * Creates a new instance of this class.
     * @param context The context used to create the instance
     */
    public ClearableEditText (final Context context) {
        this(context, null, 0);
    }

    /**
     * Creates a new instance of this class.
     * @param context The context used to create the instance
     * @param attrs The attribute set used to customize this instance
     */
    public ClearableEditText (final Context context, final AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * Creates a new instance of this class.
     * @param context The context used to create the instance
     * @param attrs The attribute set used to customize this instance
     * @param defStyle The default style to be applied to this instance
     */
    public ClearableEditText (final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);

        final LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.clearable_edit_text, this, true);
    }

    @Override
    protected void onFinishInflate () {
        super.onFinishInflate();

        final EditText editField = (EditText) findViewById(R.id.edit_text_field);
        final ImageButton clearButton = (ImageButton) findViewById(R.id.edit_text_clear);

        //Set text listener so we can show/hide the close button based on whether or not it has text
        editField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged (final CharSequence charSequence, final int i, final int i2, final int i3) {
                //Do nothing here
            }

            @Override
            public void onTextChanged (final CharSequence charSequence, final int i, final int i2, final int i3) {
                //Do nothing here
            }

            @Override
            public void afterTextChanged (final Editable editable) {
                clearButton.setVisibility(editable.length() > 0 ? View.VISIBLE : View.INVISIBLE);
            }
        });

        //Set the click listener for the button to clear the text. The act of clearing the text will hide this button because of the
        //text listener
        clearButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick (final View view) {
                editField.setText("");
            }
        });
    }

    @Override
    protected void onLayout (final boolean changed, final int left, final int top, final int right, final int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        //Set padding here in the code so the text doesn't run into the close button. This could be done in the XML layout, but then if
        //the size of the image changes then we constantly need to tweak the padding when the image changes. This way it happens automatically
        if (!mPaddingSet) {
            final EditText editField = (EditText) findViewById(R.id.edit_text_field);
            final ImageButton clearButton = (ImageButton) findViewById(R.id.edit_text_clear);

            editField.setPadding(editField.getPaddingLeft(), editField.getPaddingTop(), clearButton.getWidth(), editField.getPaddingBottom());
            mPaddingSet = true;
        }
    }
}

เพื่อให้คำตอบนี้สอดคล้องกับคำถามควรดำเนินการขั้นตอนต่อไปนี้:

  1. เปลี่ยน drawable ทรัพยากรเป็นสิ่งที่คุณต้องการ ... ในกรณีของฉันมันคือ X สีเทา
  2. เพิ่มฟังการเปลี่ยนแปลงการโฟกัสไปที่ข้อความแก้ไข ...

3

และถ้า drawable อยู่ด้านซ้ายนี่จะช่วยคุณ (สำหรับผู้ที่ทำงานกับเค้าโครง RTL)

 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() <= (searchbox.getLeft() + searchbox.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width())) {
                                     // your action here

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

นี่เป็นการผสมตำแหน่งสัมบูรณ์ "getRawX" กับตำแหน่งสัมพัทธ์ "getRight" หากคุณตั้งค่าระยะขอบด้านขวาหรือซ้ายบน editText คุณจะเห็นว่าการแบ่งดังกล่าวเป็นอย่างไรเมื่อมีการคลิกเกิดขึ้นบนพิกัดที่ไม่ถูกต้อง
Sotti

3

เพียงคัดลอกวางรหัสต่อไปนี้และมันจะหลอกลวง

editMsg.setOnTouchListener(new View.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() >= (editMsg.getRight() - editMsg.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                    // your action here

                    Toast.makeText(ChatActivity.this, "Message Sent", Toast.LENGTH_SHORT).show();
                    return true;
                }
            }
            return false;
        }
    });

1
สิ่งนี้ใช้ได้สำหรับฉัน แต่ฉันต้องใช้ getX () แทน getRawX () ฉันคิดว่า getRawX () ใช้ได้เฉพาะเมื่อมุมมองอยู่ที่ขอบด้านซ้ายของหน้าจอ
เกล็น

1
การคำนวณตำแหน่งไม่ถูกต้อง กำลังผสมพิกัดแบบสัมบูรณ์ "getRawX ()" กับรายการที่เกี่ยวข้องเช่น "getRight ()"
Sotti

3

ไม่มีการแก้ปัญหาก่อนหน้านี้ทำงานสำหรับฉันในXamarin Android ฉันสามารถรับฟังการคลิกที่ถูกต้องซึ่งใช้งานได้โดยใช้สิ่งต่อไปนี้:

สร้างOnEditTextTouchฟังเหตุการณ์ต่อไปนี้:

  private void OnEditTextTouch(object sender, View.TouchEventArgs e)
    {
        var rightDrawable = _autoCompleteTextViewSearch.GetCompoundDrawables()[2];

        if (rightDrawable == null || e.Event.Action != MotionEventActions.Up)
        {
            e.Handled = false;

            return;
        }

        if (e.Event.GetX() >= _autoCompleteTextViewSearch.Width - _autoCompleteTextViewSearch.TotalPaddingRight)
        {
            // Invoke your desired action here.

            e.Handled = true;
        }

        // Forward the event along to the sender (crucial for default behaviour)
        (sender as AutoCompleteTextView)?.OnTouchEvent(e.Event);
    }

สมัครสมาชิกกับกิจกรรม Touch:

_autoCompleteTextViewSearch.Touch += OnEditTextTouch;

2

มันเยี่ยมมาก แต่ทำไมไม่ทำให้มันเรียบง่ายจริงๆ?

ฉันต้องเผชิญกับสิ่งนั้นเมื่อไม่นานที่ผ่านมา ... และ android touchlistiner ใช้งานได้ดี แต่ให้ข้อ จำกัด ในการใช้งาน .. และฉันมาหาวิธีแก้ไขปัญหาอื่นและฉันหวังว่าจะช่วยให้คุณ:

    <LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/zero_row">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="wrap_content"
            android:layout_height="match_parent">
            <ProgressBar
                android:id="@+id/loadingProgressBar"
                android:layout_gravity="center"
                android:layout_width="28dp"
                android:layout_height="28dp" />
        </LinearLayout>
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:background="@drawable/edittext_round_corners"
            android:layout_height="match_parent"
            android:layout_marginLeft="5dp">
            <ImageView
                android:layout_width="28dp"
                android:layout_height="28dp"
                app:srcCompat="@android:drawable/ic_menu_search"
                android:id="@+id/imageView2"
                android:layout_weight="0.15"
                android:layout_gravity="center|right"
                android:onClick="OnDatabaseSearchEvent" />
            <EditText
                android:minHeight="40dp"
                android:layout_marginLeft="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/edittext_round_corners"
                android:inputType="textPersonName"
                android:hint="Search.."
                android:textColorHint="@color/AndroidWhite"
                android:textColor="@color/AndroidWhite"
                android:ems="10"
                android:id="@+id/e_d_search"
                android:textCursorDrawable="@color/AndroidWhite"
                android:layout_weight="1" />
            <ImageView
                android:layout_width="28dp"
                android:layout_height="28dp"
                app:srcCompat="@drawable/ic_oculi_remove2"
                android:id="@+id/imageView3"
                android:layout_gravity="center|left"
                android:layout_weight="0.15"
                android:onClick="onSearchEditTextCancel" />
        </LinearLayout>

        <!--android:drawableLeft="@android:drawable/ic_menu_search"-->
        <!--android:drawableRight="@drawable/ic_oculi_remove2"-->

    </LinearLayout>

</LinearLayout>

ป้อนคำอธิบายรูปภาพที่นี่ ตอนนี้คุณสามารถสร้างฟังหรือเหตุการณ์ของ ImageClick และทำสิ่งที่คุณต้องการด้วยข้อความ ไฟล์ edittext_round_corners.xml นี้

<item android:state_pressed="false" android:state_focused="false">
    <shape>
        <gradient
            android:centerY="0.2"
            android:startColor="@color/colorAccent"
            android:centerColor="@color/colorAccent"
            android:endColor="@color/colorAccent"
            android:angle="270"
            />
        <stroke
            android:width="0.7dp"
            android:color="@color/colorAccent" />
        <corners
            android:radius="5dp" />
    </shape>
</item>


ปัญหาของวิธีการนี้คือการแตกสลายทันทีที่คุณเริ่มเปลี่ยนขนาดตัวอักษรใน EditText คุณอาจคิดว่าเป็นเพียงด้านของนักพัฒนา แต่ไม่ไกลเท่าที่อุปกรณ์มีขนาดตัวอักษรในการตั้งค่าคุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยใช้ dp แทน sp บน EditText แต่มันทำให้สิ่งเลวร้ายลง ปัญหาอื่น ๆ คือสิ่งต่าง ๆ เช่นการจัดการ EditTexts หลายบรรทัด
Sotti

ฉันไม่เคยใช้มันสำหรับการค้นหาหลายบรรทัดดังนั้นฉันไม่เคยคิดเลยว่าปัญหานี้อาจปรากฏขึ้น การบล็อกหลายสายอาจจะช่วยได้ คุณสามารถแนบภาพหน้าจอของแอพหรือมุมมองเพื่อดูว่าเกิดอะไรขึ้น? และฉันจะพยายามแก้ไขและอาจช่วยคุณ (แก้ไขรหัสนี้) และฉันสำหรับการใช้งานในอนาคต ขอบคุณ
Jevgenij Kononov

มันง่ายมากที่จะทำซ้ำมันเกิดขึ้นในหน้าตัวอย่างเค้าโครงทันทีที่คุณเพิ่ม 2 บรรทัด
Sotti

พื้นหลังสำหรับที่ควรจะเป็นEditText android:background="@android:color/transparent"
CoolMind

1

ดีกว่าที่จะมี ImageButton ด้านขวาของข้อความแก้ไขและให้เค้าโครงขอบด้านลบเพื่อทับซ้อนกับข้อความแก้ไข ตั้งฟังจาก ImageButton และดำเนินการ


1
@Override
    public boolean onTouch(View v, MotionEvent event) {

        Drawable drawableObj = getResources().getDrawable(R.drawable.search_btn);
        int drawableWidth = drawableObj.getIntrinsicWidth();

        int x = (int) event.getX();
        int y = (int) event.getY();

        if (event != null && event.getAction() == MotionEvent.ACTION_UP) {
            if (x >= (searchPanel_search.getWidth() - drawableWidth - searchPanel_search.getPaddingRight())
                    && x <= (searchPanel_search.getWidth() - searchPanel_search.getPaddingRight())

                    && y >= searchPanel_search.getPaddingTop() && y <= (searchPanel_search.getHeight() - searchPanel_search.getPaddingBottom())) {

                getSearchData();
            }

            else {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.showSoftInput(searchPanel_search, InputMethodManager.SHOW_FORCED);
            }
        }
        return super.onTouchEvent(event);

    }

1
<FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp" >

            <EditText
                android:id="@+id/edt_status_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:background="@drawable/txt_box_blank"
                android:ems="10"
                android:hint="@string/statusnote"
                android:paddingLeft="5dp"
                android:paddingRight="10dp"
                android:textColor="@android:color/black" />

            <Button
                android:id="@+id/note_del"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="right"
                android:layout_marginRight="1dp"
                android:layout_marginTop="5dp"
                android:background="@android:drawable/ic_delete" />
        </FrameLayout>

ปัญหาเกี่ยวกับวิธีการนี้คือการแตกสลายทันทีที่คุณเริ่มเปลี่ยนขนาดตัวอักษรใน EditText คุณอาจคิดว่าเป็นเพียงด้านของนักพัฒนา แต่ไม่ไกลเท่าที่อุปกรณ์มีขนาดตัวอักษรในการตั้งค่าคุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยใช้ dp แทนที่จะเป็น sp ใน EditText แต่มันทำให้สิ่งต่าง ๆ แย่ลง ปัญหาอื่น ๆ คือสิ่งต่าง ๆ เช่นการจัดการ EditTexts หลายบรรทัด
Sotti

1

สำหรับผู้ฟังที่คลิกได้

txt.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            final int DRAWABLE_LEFT = 0;

            if (event.getAction() == MotionEvent.ACTION_UP) {
                if (event.getRawX() <= (txt
                        .getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width() +
                        txt.getPaddingLeft() +
                        txt.getLeft())) {

                          //TODO do code here
                    }
                    return true;
                }
            }
            return false;
        }
    });

นี่เป็นการผสมตำแหน่งสัมบูรณ์ "getRawX" กับตำแหน่งสัมพัทธ์ "getRight" หากคุณตั้งค่าระยะขอบด้านขวาหรือซ้ายบน editText คุณจะเห็นว่าการแบ่งดังกล่าวเป็นอย่างไรเมื่อมีการคลิกเกิดขึ้นบนพิกัดที่ไม่ถูกต้อง
Sotti

1

ไม่สามารถคลิกได้ การใช้มุมมองแยกต่างหากใน LinearLayout แนวนอนนั้นสะอาดกว่าและใช้ตัวจัดการการคลิก

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:background="@color/white"
        android:layout_marginLeft="20dp"
        android:layout_marginStart="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginEnd="20dp"
        android:layout_gravity="center_horizontal"
        android:orientation="horizontal"
        android:translationZ="4dp">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="@color/white"
            android:minWidth="40dp"
            android:scaleType="center"
            app:srcCompat="@drawable/ic_search_map"/>

        <android.support.design.widget.TextInputEditText
            android:id="@+id/search_edit"
            style="@style/EditText.Registration.Map"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:hint="@string/hint_location_search"
            android:imeOptions="actionSearch"
            android:inputType="textPostalAddress"
            android:maxLines="1"
            android:minHeight="40dp" />

        <ImageView
            android:id="@+id/location_gps_refresh"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="@color/white"
            android:minWidth="40dp"
            android:scaleType="center"
            app:srcCompat="@drawable/selector_ic_gps"/>
</LinearLayout>

ปัญหาเกี่ยวกับวิธีการนี้คือการแตกสลายทันทีที่คุณเริ่มเปลี่ยนขนาดตัวอักษรใน EditText คุณอาจคิดว่าเป็นเพียงด้านของนักพัฒนา แต่ไม่ไกลเท่าที่อุปกรณ์มีขนาดตัวอักษรในการตั้งค่าคุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยใช้ dp แทน sp บน EditText แต่มันทำให้สิ่งเลวร้ายลง ปัญหาอื่น ๆ คือสิ่งต่าง ๆ เช่นการจัดการ EditTexts หลายบรรทัด
Sotti

1

สำหรับใครก็ตามที่ไม่ต้องการใช้การจัดการคลิกมหึมา RelativeLayoutคุณสามารถบรรลุเดียวกันกับ โดยที่คุณยังสามารถควบคุมตำแหน่งของ drawable ได้ฟรี

  <RelativeLayout
     android:layout_width="match_parent"
     android:layout_height="wrap_content">

   <android.support.design.widget.TextInputLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content">

     <android.support.design.widget.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
      />
     </android.support.design.widget.TextInputLayout>
     <ImageView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentEnd="true"
       android:layout_centerInParent="true"
       android:src="@drawable/ic_undo"/>
    </RelativeLayout>

ImageViewตำแหน่งจะเป็นเช่นเดียวกับที่คุณจะใช้drawableEnd- บวกคุณไม่จำเป็นต้องทุกจัดการสัมผัสฟัง เพียงแค่คลิกฟังสำหรับImageViewและคุณก็พร้อมที่จะไป


ปัญหาเกี่ยวกับวิธีการนี้คือการแตกสลายทันทีที่คุณเริ่มเปลี่ยนขนาดตัวอักษรใน EditText คุณอาจคิดว่าเป็นเพียงด้านของนักพัฒนา แต่ไม่ไกลเท่าที่อุปกรณ์มีขนาดตัวอักษรในการตั้งค่าคุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยใช้ dp แทน sp บน EditText แต่มันทำให้สิ่งเลวร้ายลง ปัญหาอื่น ๆ คือสิ่งต่าง ๆ เช่นการจัดการ EditTexts หลายบรรทัด
Sotti

1

สิ่งนี้ได้ผลสำหรับฉัน :) สิ่งนี้อาจช่วยคุณได้เช่นกัน

edit_account_name.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                if (event.getRawX() >= (edit_account_name.getRight())) {
                    //clicked
                   return true;
                }
            }
            return false;
        }
    });

นี่เป็นการผสมตำแหน่งสัมบูรณ์ "getRawX" กับตำแหน่งสัมพัทธ์ "getRight" หากคุณตั้งค่าระยะขอบด้านขวาหรือซ้ายบน editText คุณจะเห็นว่าการแบ่งดังกล่าวเป็นอย่างไรเมื่อมีการคลิกเกิดขึ้นบนพิกัดที่ไม่ถูกต้อง
Sotti

ฉันได้เพิ่มระยะขอบด้านขวาบนข้อความแก้ไขรหัสของฉันยังคงทำงานได้อย่างสมบูรณ์
zohaib khaliq

1

ฉันเห็นวิธีแก้ไขปัญหาต่าง ๆ แต่ฉันไม่มั่นใจในสิ่งเหล่านั้น อาจซับซ้อนหรือเรียบง่ายเกินไป (ไม่สามารถใช้ซ้ำได้)

นี่เป็นวิธีการโปรดของฉันในขณะนี้:

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();
}

คุณสามารถดูแก่นสารที่นี่


1

ทำตามโค้ดด้านล่างเพื่อวาดได้ทั้งซ้าย, ขวา, ขึ้น - ลง, คลิก:

edittextview_confirmpassword.setOnTouchListener(new View.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() >= (edittextview_confirmpassword.getRight() - edittextview_confirmpassword.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                // your action here                    edittextview_confirmpassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                return true;
            }
        }else{
            edittextview_confirmpassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

        }
        return false;
    }
});

}


1

ฉันใช้งานใน Kotlin

edPassword.setOnTouchListener { _, event ->
            val DRAWABLE_RIGHT = 2
            val DRAWABLE_LEFT = 0
            val DRAWABLE_TOP = 1
            val DRAWABLE_BOTTOM = 3
            if (event.action == MotionEvent.ACTION_UP) {
                if (event.rawX >= (edPassword.right - edPassword.compoundDrawables[DRAWABLE_RIGHT].bounds.width())) {
                    edPassword.setText("")
                    true
                }
            }
            false
        }

0

นี่คือทางออกง่ายๆของฉันเพียงแค่วางImageButtonเหนือEditText:

<RelativeLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

  <EditText android:id="@+id/editTextName"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:imeOptions="actionSearch"
    android:inputType="text"/>

  <ImageButton android:id="@+id/imageViewSearch"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_action_search"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"/>

</RelativeLayout>

0

ฉันอยากจะแนะนำวิธีการที่เหลือ drawable! ฉันลองใช้รหัสนี้และใช้งานได้

txtsearch.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            final int DRAWABLE_LEFT = 0;
            int start=txtsearch.getSelectionStart();
            int end=txtsearch.getSelectionEnd();
            if(event.getAction() == MotionEvent.ACTION_UP) {
                if(event.getRawX() <= (txtsearch.getLeft() + txtsearch.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width())) {
                    //Do your action here
                    return true;
                }

            }
            return false;
        }
    });
}

นี่เป็นการผสมตำแหน่งสัมบูรณ์ "getRawX" กับตำแหน่งสัมพัทธ์ "getRight" หากคุณตั้งค่าระยะขอบด้านขวาหรือซ้ายบน editText คุณจะเห็นว่าการแบ่งดังกล่าวเป็นอย่างไรเมื่อมีการคลิกเกิดขึ้นบนพิกัดที่ไม่ถูกต้อง
Sotti

0

ฉันใช้ @aristo_sh คำตอบใน Mono.Droid (Xamarin) เนื่องจากเป็นวิธีที่ไม่ระบุชื่อผู้แทนคุณไม่สามารถคืนค่าจริงหรือเท็จคุณต้องรับ e.Event.Handled ฉันยังซ่อนแป้นพิมพ์เมื่อคลิก

editText.Touch += (sender, e) => {
                    e.Handled = false;
                    if (e.Event.Action == MotionEventActions.Up)
                    {
                        if (e.Event.RawX >= (bibEditText.Right - (bibEditText.GetCompoundDrawables()[2]).Bounds.Width()))
                        {
                            SearchRunner();
                            InputMethodManager manager = (InputMethodManager)GetSystemService(InputMethodService);
                            manager.HideSoftInputFromWindow(editText.WindowToken, 0);
                            e.Handled = true;
                        }
                    }
                };

0

การแบ่งปันโซลูชันทั่วไปของฉันสำหรับการจัดการการคลิกและสัมผัสเหตุการณ์ผสม TextView

ก่อนอื่นเราต้องใช้ตัวจัดการเหตุการณ์แบบสัมผัส:

/**
 * Handles compound drawable touch events.
 * Will intercept every event that happened inside (calculated) compound drawable bounds, extended by fuzz.
 * @see TextView#getCompoundDrawables()
 * @see TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)
 */
public abstract class CompoundDrawableTouchListener implements View.OnTouchListener {

    private final String LOG_TAG = "CmpDrawableTouch";

    private final int fuzz;

    public static final int LEFT = 0;
    public static final int TOP = 1;
    public static final int RIGHT = 2;
    public static final int BOTTOM = 3;
    private static final int[] DRAWABLE_INDEXES = {LEFT, TOP, RIGHT, BOTTOM};

    /**
     * Default constructor
     */
    public CompoundDrawableTouchListener() {
        this(0);
    }

    /**
     * Constructor with fuzz
     * @param fuzz desired fuzz in px
     */
    public CompoundDrawableTouchListener(int fuzz) {
        this.fuzz = fuzz;
    }

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        if (!(view instanceof TextView)) {
            Log.e(LOG_TAG, "attached view is not instance of TextView");
            return false;
        }

        TextView textView = (TextView) view;
        Drawable[] drawables = textView.getCompoundDrawables();
        int x = (int) event.getX();
        int y = (int) event.getY();

        for (int i : DRAWABLE_INDEXES) {
            if (drawables[i] == null) continue;
            Rect bounds = getRelativeBounds(i, drawables[i], textView);
            Rect fuzzedBounds = addFuzz(bounds);

            if (fuzzedBounds.contains(x, y)) {
                MotionEvent relativeEvent = MotionEvent.obtain(
                    event.getDownTime(),
                    event.getEventTime(),
                    event.getAction(),
                    event.getX() - bounds.left,
                    event.getY() - bounds.top,
                    event.getMetaState());
                return onDrawableTouch(view, i, bounds, relativeEvent);
            }
        }

        return false;
    }

    /**
     * Calculates compound drawable bounds relative to wrapping view
     * @param index compound drawable index
     * @param drawable the drawable
     * @param view wrapping view
     * @return {@link Rect} with relative bounds
     */
    private Rect getRelativeBounds(int index, @NonNull Drawable drawable, View view) {
        Rect drawableBounds = drawable.getBounds();
        Rect bounds = new Rect();

        switch (index) {
            case LEFT:
                bounds.offsetTo(view.getPaddingLeft(),
                    view.getHeight() / 2 - bounds.height() / 2);
                break;

            case TOP:
                bounds.offsetTo(view.getWidth() / 2 - bounds.width() / 2,
                    view.getPaddingTop());
                break;

            case RIGHT:
                bounds.offsetTo(view.getWidth() - view.getPaddingRight() - bounds.width(),
                    view.getHeight() / 2 - bounds.height() / 2);
                break;

            case BOTTOM:
                bounds.offsetTo(view.getWidth() / 2 - bounds.width() / 2,
                    view.getHeight() - view.getPaddingBottom() - bounds.height());
                break;
        }

        return bounds;
    }

    /**
     * Expands {@link Rect} by given value in every direction relative to its center
     * @param source given {@link Rect}
     * @return result {@link Rect}
     */
    private Rect addFuzz(Rect source) {
        Rect result = new Rect();
        result.left = source.left - fuzz;
        result.right = source.right + fuzz;
        result.top = source.top - fuzz;
        result.bottom = source.bottom + fuzz;
        return result;
    }

    /**
     * Compound drawable touch-event handler
     * @param v wrapping view
     * @param drawableIndex index of compound drawable which recicved the event
     * @param drawableBounds {@link Rect} with compound drawable bounds relative to wrapping view.
     * Fuzz not included
     * @param event event with coordinated relative to wrapping view - i.e. within {@code drawableBounds}.
     * If using fuzz, may return negative coordinates.
     */
    protected abstract boolean onDrawableTouch(View v, int drawableIndex, Rect drawableBounds, MotionEvent event);
}

ตอนนี้คุณสามารถประมวลผลกิจกรรมการสัมผัสใด ๆ ในรายการใดก็ได้ที่สามารถดึงได้จาก TextView ที่คุณชอบดังนี้:

textView1.setOnTouchListener(new CompoundDrawableTouchListener() {
            @Override
            protected void onDrawableTouch(View v, int drawableIndex, Rect drawableBounds, MotionEvent event) {
                switch(v.getId()) {
                    case R.id.textView1:
                        switch(drawableIndex) {
                            case CompoundDrawableTouchListener.RIGHT:
                                doStuff();
                                break;
                        }
                        break;
                }
            }
        });

สนใจเฉพาะการคลิกหรือไม่ เพียงกรองโดยการกระทำ MotionEvent:

/**
 * Handles compound drawable click events.
 * @see TextView#getCompoundDrawables()
 * @see TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)
 * @see CompoundDrawableTouchListener
 */
public abstract class CompoundDrawableClickListener extends CompoundDrawableTouchListener {

    /**
     * Default constructor
     */
    public CompoundDrawableClickListener() {
        super();
    }

     /**
     * Constructor with fuzz
     * @param fuzz desired fuzz in px
     */
    public CompoundDrawableClickListener(int fuzz) {
        super(fuzz);
    }

    @Override
    protected void onDrawableTouch(View v, int drawableIndex, Rect drawableBounds, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) onDrawableClick(v, drawableIndex);
        return true;
    }

    /**
     * Compound drawable touch-event handler
     * @param v wrapping view
     * @param drawableIndex index of compound drawable which recicved the event
     */
    protected abstract void onDrawableClick(View v, int drawableIndex);
}

เราสามารถจัดการกับการคลิกบนสารประกอบใด ๆ ที่ดึงได้จาก TextView ใด ๆ :

textView1.setOnTouchListener(new CompoundDrawableClickListener() {
            @Override
            protected void onDrawableClick(View v, int drawableIndex) {
                switch(v.getId()) {
                    case R.id.textView1:
                        switch(drawableIndex) {
                            case CompoundDrawableTouchListener.RIGHT:
                                doStuff();
                                break;
                        }
                        break;
                }
            }
        });

หวังว่าคุณจะชอบมันเหมือนที่ฉันทำ ฉันจะพยายามปรับปรุงให้ทันสมัยอยู่เสมอส่วนที่เกี่ยวข้องหากมีการเปลี่ยนแปลงอะไร


0

ฉันได้สร้างคลาส listener แบบสัมผัสที่เรียบง่ายแบบกำหนดเองแทน EditText แบบกำหนดเอง

public class MyTouchListener implements View.OnTouchListener {
private EditText editText;

public MyTouchListener(EditText editText) {
    this.editText = editText;

    setupDrawable(this.editText);
}

private void setupDrawable(final EditText editText) {
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if(s.length()>0)
                editText.setCompoundDrawablesWithIntrinsicBounds(0,0, R.drawable.clearicon,0);
            else
                editText.setCompoundDrawablesWithIntrinsicBounds(0,0, 0,0);

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_UP) {
        if(editText.getCompoundDrawables()[2]!=null){
            if(event.getX() >= (editText.getRight()- editText.getLeft() - editText.getCompoundDrawables()[2].getBounds().width())) {
                editText.setText("");
            }
        }
    }
    return false;

}

}

จะไม่มี drawable เมื่อ EditText ว่างเปล่า Drawable จะแสดงเมื่อเราเริ่มแก้ไขเพื่อล้าง EditText

คุณสามารถตั้งค่าฟังแบบสัมผัสได้

mEditText.setOnTouchListener (ใหม่ MyTouchListener (mEditText));


มันค่อนข้างสับสนว่า TouchListener นั้นสามารถจัดการกับการมองเห็นที่ชัดเจนและการกระทำที่ชัดเจน นั่นไม่ใช่ความรับผิดชอบของผู้ฟังแบบสัมผัสและชื่อของคลาสนั้นทำให้เข้าใจผิด เช่นเดียวกับที่คุณกำลังคำนวณตำแหน่งสัมพัทธ์ไม่จำเป็นต้องกำจัดระยะขอบออกจากสมการ getRight - ความกว้างจะทำได้
Sotti
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.