📜 ⬆️ ⬇️

Custom EditText with three buttons on the right

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

The solution was quite concise and reliably working. But then I wanted to go further and make 2-3 buttons, is there any other functionality that can be hung on them, for example, select from the list that opens in a separate window or enable / disable editing mode to protect the field from accidental changes.

So, let's begin:
1. Create a new project with an 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, you need to create attrs.xml with the following content:

 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyCustomEditText"> <attr name="drawableRight2" format="reference"/> <attr name="drawableRight3" format="reference"/> </declare-styleable> </resources> 

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

 <ru.vlsoft.mycustomedittext.MyCustomEditText android:id="@+id/customEditText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:drawableEnd="@drawable/one" android:drawableRight="@drawable/one" android:textAppearance="?android:attr/textAppearanceLarge" app:drawableRight2="@drawable/two" android:singleLine="true" app:drawableRight3="@drawable/three" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" /> 

5. Well, the last step is to add an onTouchListener event handler to 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 will come in handy, thank you for your attention.

Source: https://habr.com/ru/post/273589/


All Articles