Custom EditText with three buttons on the right

During the development of one application, I wanted to add a clear text button to the EditText component. The solution was found quickly enough and consisted in catching the coordinates of the touch, and if the touch happened over the right background image (drawableRight), then treat it as a button click (clear text), otherwise - in a standard way for this component.

The solution turned out to be quite concise and reliable. But then I wanted to go further and make 2-3 buttons, you never know what other functionality you can hang on them, for example, a choice from the list that opens in a separate window or switching on / off the editing mode to protect the field from accidental changes.

So, let's start:
1. Create a new project with empty activity (Android Studio 1.5.1 development environment).

2. Add a new class and call it MyCustomEditText, full listing:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
public class MyCustomEditText extends EditText {
    Bitmap drawableRight; //стандартный drawable справа
    Bitmap drawableRight2; //то, ЧТО будем рисовать
    Bitmap drawableRight3; //то, ЧТО будем рисовать
    Paint paint; //то, ЧЕМ будем рисовать
    public MyCustomEditText(Context context) {
        super(context);
        init();
    }
    public MyCustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        initDrawables(attrs);
        init();
    }
    public MyCustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initDrawables(attrs);
        init();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (drawableRight != null) {
            //рисуем drawableRight2 только при наличии drawableRight
            if (drawableRight2 != null) {
                canvas.drawBitmap(drawableRight2, getWidth() + getScrollX() - drawableRight.getWidth() * 2, (getHeight() - drawableRight2.getHeight()) / 2, paint);
                //рисуем drawableRight3 только при наличии drawableRight2
                if (drawableRight3 != null) {
                    canvas.drawBitmap(drawableRight3, getWidth() + getScrollX() - drawableRight.getWidth() * 3, (getHeight() - drawableRight3.getHeight()) / 2, paint);
                }
            }
        }
    }
    /**
     * Returns the right padding of the view, plus space for the right
     * Drawable if any.
     */
    @Override
    public int getCompoundPaddingRight() {
        //здесь мы устанавливаем отступ справа, чтобы каретка не наезжала на наши кнопки
        int paddingRight = super.getCompoundPaddingRight();
        if (drawableRight2 != null) {
            paddingRight = paddingRight + drawableRight2.getWidth();
        }
        if (drawableRight3 != null) {
            paddingRight = paddingRight + drawableRight3.getWidth();
        }
        return paddingRight;
    }
    private void initDrawables(AttributeSet attrs) {
        //инициализируем наши drawables, если были заполнены соответствующие атрибуты
        for (int i = 0; i < attrs.getAttributeCount(); i++) {
            if (attrs.getAttributeName(i).equals("drawableRight")) {
                drawableRight = BitmapFactory.decodeResource(getResources(), attrs.getAttributeResourceValue(i, 0));
            }
            if (attrs.getAttributeName(i).equals("drawableRight2")) {
                drawableRight2 = BitmapFactory.decodeResource(getResources(), attrs.getAttributeResourceValue(i, 0));
            }
            if (attrs.getAttributeName(i).equals("drawableRight3")) {
                drawableRight3 = BitmapFactory.decodeResource(getResources(), attrs.getAttributeResourceValue(i, 0));
            }
        }
    }
    private void init() {
        paint = new Paint();
    }
}

3. In order for our component to have the properties we need, create attrs.xml with the following contents:


4. Then you can set the values ​​of these properties in the markup file:


5. Well, the last step will be to add the onTouchListener event handler in the main activity, the full listing of which is below:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyCustomEditText customEditText = (MyCustomEditText) findViewById(R.id.customEditText);
        customEditText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    MyCustomEditText editText = (MyCustomEditText) v;
                    //подразумеваем, что все 3 изображения справа указаны
                    //и т.к. все изображения у нас одного размера, то будем отталкиваться от размера самого правого
                    int drawableSize = editText.getCompoundDrawables()[2].getBounds().width();
                    if (event.getRawX() >= editText.getRight() - drawableSize) {
                        Log.i("sdf", "one");
                        return true;
                    } else if (event.getRawX() >= editText.getRight() - drawableSize * 2) {
                        Log.i("sdf", "two");
                        return true;
                    } else if (event.getRawX() >= editText.getRight() - drawableSize * 3) {
                        Log.i("sdf", "three");
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            }
        });
    }
}

The whole project can be downloaded here . I hope someone comes in handy, thanks for your attention.

Also popular now: