Android:如何通过右侧的交叉按钮清除EditText

时间:2014-04-20 15:23:36

标签: android android-widget android-edittext android-drawable

我为搜索创建了一个EditText,其左侧包含一个搜索图标,位于图标的右侧:

<EditText
    android:id="@+id/Search"
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    android:drawableLeft="@android:drawable/ic_menu_search"
    android:drawableRight="@android:drawable/ic_delete"
    android:hint="Search Product .." >
</EditText>

我想知道当我点击十字按钮时如何清除EditText的内容。

提前谢谢。

5 个答案:

答案 0 :(得分:16)

来自Handling click events on a drawable within an EditText

的@aristo_sh的改进答案
    mQueryEditText.setOnTouchListener(new OnTouchListener() {
        final int DRAWABLE_LEFT = 0;
        final int DRAWABLE_TOP = 1;
        final int DRAWABLE_RIGHT = 2;
        final int DRAWABLE_BOTTOM = 3;
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                int leftEdgeOfRightDrawable = mQueryEditText.getRight() 
                      - mQueryEditText.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width();
                // when EditBox has padding, adjust leftEdge like
                // leftEdgeOfRightDrawable -= getResources().getDimension(R.dimen.edittext_padding_left_right);
                if (event.getRawX() >= leftEdgeOfRightDrawable) {
                    // clicked on clear icon
                    mQueryEditText.setText("");
                    return true;
                }
            }
            return false;
        }
    });

答案 1 :(得分:4)

我更喜欢使用另一个客户Edittex作为以下可清除的edittext。您可以在xml中将其用作普通的edittext。要收听明确的事件,您可以setListener

ClearableEdittext

/** Copyright 2014 Alex Yanchenko
 * To change clear icon, set
 * <p/>
 * <pre>
 * android:drawableRight="@drawable/custom_icon"
 * </pre>
 */
public class ClearableEditText extends EditText implements OnTouchListener,
        OnFocusChangeListener, TextWatcherAdapter.TextWatcherListener {

    public interface Listener {
        void didClearText();
    }

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    private Drawable xD;
    private Listener listener;

    public ClearableEditText(Context context) {
        super(context);
        init();
    }

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

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

    @Override
    public void setOnTouchListener(OnTouchListener l) {
        this.l = l;
    }

    @Override
    public void setOnFocusChangeListener(OnFocusChangeListener f) {
        this.f = f;
    }

    private OnTouchListener l;
    private OnFocusChangeListener f;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (getCompoundDrawables()[2] != null) {
            boolean tappedX = event.getX() > (getWidth() - getPaddingRight() - xD
                    .getIntrinsicWidth());
            if (tappedX) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    setText("");
                    if (listener != null) {
                        listener.didClearText();
                    }
                }
                return true;
            }
        }
        if (l != null) {
            return l.onTouch(v, event);
        }
        return false;
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            setClearIconVisible(!TextUtils.isEmpty(getText()));
        } else {
            setClearIconVisible(false);
        }
        if (f != null) {
            f.onFocusChange(v, hasFocus);
        }
    }

    @Override
    public void onTextChanged(EditText view, String text) {
        if (isFocused()) {
            setClearIconVisible(!TextUtils.isEmpty(text));
        }
    }

    private void init() {
        xD = getCompoundDrawables()[2];
        if (xD == null) {
            xD = getResources()
                    .getDrawable(android.R.drawable.presence_offline);
        }
        xD.setBounds(0, 0, xD.getIntrinsicWidth(), xD.getIntrinsicHeight());
        setClearIconVisible(false);
        super.setOnTouchListener(this);
        super.setOnFocusChangeListener(this);
        addTextChangedListener(new TextWatcherAdapter(this, this));
    }

    protected void setClearIconVisible(boolean visible) {
        Drawable x = visible ? xD : null;
        setCompoundDrawables(getCompoundDrawables()[0],
                getCompoundDrawables()[1], x, getCompoundDrawables()[3]);
    }
}

修改:我忘记了TextWatcherAdapter,实际上它只是一个客户TextWatcher

public class TextWatcherAdapter implements TextWatcher {

public interface TextWatcherListener {

    void onTextChanged(EditText view, String text);

}

private final EditText view;
private final TextWatcherListener listener;

public TextWatcherAdapter(EditText editText, TextWatcherListener listener) {
    this.view = editText;
    this.listener = listener;
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    listener.onTextChanged(view, s.toString());
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
                              int after) {
    // pass
}

@Override
public void afterTextChanged(Editable s) {
    // pass
}
}

答案 2 :(得分:2)

试试这个:

activity_main.xml中

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="9dp"
    android:padding="5dp">

    <EditText
        android:id="@+id/Search"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:drawableLeft="@android:drawable/ic_menu_search"
        android:hint="Search Product .." >
    </EditText>

    <Button
        android:id="@+id/clearText"
        android:layout_width="23dp"
        android:layout_height="23dp"
        android:layout_marginRight="10dp"
        android:layout_gravity="right|bottom"
        android:layout_marginBottom="10dp"
        android:background="@android:drawable/ic_delete"
        android:onClick="clear"/>

</FrameLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    EditText mEditText;
    Button mClearText;

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

        mEditText = (EditText) findViewById(R.id.Search);
        mClearText = (Button) findViewById(R.id.clearText);

        //initially clear button is invisible
        mClearText.setVisibility(View.INVISIBLE);

        //clear button visibility on text change
        mEditText.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable s) {
                //do nothing
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                //do nothing
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if(s.length() != 0) {
                    mClearText.setVisibility(View.VISIBLE);
                } else {
                    mClearText.setVisibility(View.GONE);
                }
            }
        });

    }

    //clear button onclick
    public void clear(View view) {
        mEditText.setText("");
        mClearText.setVisibility(View.GONE);
    }

}

答案 3 :(得分:0)

我做过的例子:

mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_UP){
                // 100 is a fix value for the moment but you can change it
                // according to your view
                if (motionEvent.getX()>(view.getWidth()-100)){
                    ((EditText)view).setText("");
                }
            }
            return false;
        }
    });

    mPasswordView.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            if(s.toString().trim().length()==0){
                mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            } else {
                mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_black_24dp, 0);
            }
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                                      int after) {
            // TODO Auto-generated method stub
            mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);

        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            if (s.toString().trim().length() == 0) {
                mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            } else {
                mPasswordView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_black_24dp, 0);
            }
        }
    });

答案 4 :(得分:0)

answer of Paul Verest不错,但是没有考虑填充。 这是一个关于Kotlin的左右单击示例,其中包括editText的填充(这会将可绘制的相对位置从editText的侧面移开)。

editText.setOnTouchListener(View.OnTouchListener { _, event ->
            val DRAWABLE_LEFT = 0
            val DRAWABLE_RIGHT = 2

            if (event.action == MotionEvent.ACTION_UP) {
                if (event.x <= editText.compoundDrawables[DRAWABLE_LEFT].bounds.width() + (2 * editText.paddingStart)) {
                    // Left drawable clicked
                    return@OnTouchListener true
                }
                if (event.x >= editText.right - editText.compoundDrawables[DRAWABLE_RIGHT].bounds.width() - (2 * editText.paddingEnd)) {
                    // Right drawable clicked
                    return@OnTouchListener true
                }
            }
            false
        })

注意:

  • 我使用event.x而不是event.rawX来获取点击位置。 event.rawX是屏幕上的原始X坐标,它没有考虑editText的位置(例如,使editText处于空白位置的边距限制了屏幕的裁剪)。 event.x是相对于editText本身左边界的x坐标,这使计算更容易理解。
  • 在使元素可单击时始终要考虑填充!当然,如果使用editText填充将可绘制对象移得太远,则使完整的填充可点击是没有意义的。就我而言,两次使用editText.paddingStart效果很好,因此可绘制对象的两面都可以单击。您可能会考虑只对starting-drawable的左侧使用一次此填充,并为右侧填充添加editText.compoundDrawablePadding-这是drawable和text之间的填充。当然,您也可以根据自己的喜好使用一些恒定的dp值。 this blog很好地解释了可点击填充的概念。