Optimizar Clic en Drawable EditText para Mejor UX

Advertisement

La función drawable en EditText permite a los desarrolladores agregar iconos a los lados de los campos de entrada en Android. Sin embargo, implementar el clic en drawables de EditText requiere un enfoque específico usando OnTouchListener. En esta guía práctica, aprenderá técnicas probadas con código listo para usar optimizado para el mejor rendimiento y experiencia de usuario.

Advertisement
Implementación de clic en drawable EditText Android con OnTouchListener
Demostración de clic en drawable EditText mostrando interacción fluida y retroalimentación responsiva

Entendiendo los Conceptos de Clic en Drawable EditText

El EditText de Android soporta la colocación de drawables en cuatro posiciones diferentes: inicio, superior, final e inferior. Para manejar clics en estos elementos, necesita usar OnTouchListener ya que no existe un método onClick dedicado. Este enfoque permite la detección precisa de coordenadas de toque y comparación con el área del drawable.

Como desarrollador, entender el mecanismo de clic en drawable EditText es crucial para crear experiencias de usuario intuitivas. Esta técnica se usa comúnmente en formularios de entrada, campos de búsqueda y controles numéricos en aplicaciones Android modernas.

Advertisement

Implementación de Layout XML para Drawables

Primero, cree un diseño con EditText que tenga drawables en las propiedades drawableStart y drawableEnd. Asegúrese de haber agregado los iconos requeridos en la carpeta res/drawable con tamaños y resoluciones apropiados.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <EditText
        android:id="@+id/editText1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:drawableStart="@drawable/ic_baseline_remove_circle_24"
        android:drawableEnd="@drawable/ic_baseline_add_circle_24"
        android:drawablePadding="8dp"
        android:ems="10"
        android:gravity="center_horizontal"
        android:inputType="number"
        android:text="1"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Configuración de OnTouchListener en MainActivity

Aquí está la implementación completa de OnTouchListener para detectar clics en drawables. Use constantes de posición de drawables y calcule áreas de límite de toque con precisión para una interacción confiable.

Advertisement
public class MainActivity extends AppCompatActivity {

    private static final int DRAWABLE_LEFT = 0;
    private static final int DRAWABLE_RIGHT = 2;
    
    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setupDrawableClickListeners();
    }

    private void setupDrawableClickListeners() {
        EditText myText = findViewById(R.id.editText1);
        myText.setOnTouchListener((view, motionEvent) -> {
            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                Drawable[] drawables = myText.getCompoundDrawables();
                
                // Detectar clic en drawable final (derecha)
                if (isDrawableClick(motionEvent, myText, drawables, DRAWABLE_RIGHT)) {
                    incrementValue();
                    return true;
                }
                
                // Detectar clic en drawable inicial (izquierda)
                if (isDrawableClick(motionEvent, myText, drawables, DRAWABLE_LEFT)) {
                    decrementValue();
                    return true;
                }
            }
            return false;
        });
    }

    private boolean isDrawableClick(MotionEvent event, EditText editText, 
                                   Drawable[] drawables, int drawableIndex) {
        if (drawables[drawableIndex] == null) {
            return false;
        }
        
        int drawableWidth = drawables[drawableIndex].getBounds().width();
        float x = event.getRawX();
        
        switch (drawableIndex) {
            case DRAWABLE_RIGHT:
                return x >= (editText.getRight() - drawableWidth - editText.getPaddingRight());
            case DRAWABLE_LEFT:
                return x <= (editText.getLeft() + drawableWidth + editText.getPaddingLeft());
            default:
                return false;
        }
    }

    private void incrementValue() {
        EditText myText = findViewById(R.id.editText1);
        try {
            int value = Integer.parseInt(myText.getText().toString());
            myText.setText(String.valueOf(value + 1));
        } catch (NumberFormatException e) {
            myText.setText("1");
        }
    }

    private void decrementValue() {
        EditText myText = findViewById(R.id.editText1);
        try {
            int value = Integer.parseInt(myText.getText().toString());
            if (value > 1) {
                myText.setText(String.valueOf(value - 1));
            }
        } catch (NumberFormatException e) {
            myText.setText("1");
        }
    }
}

Artículos Recientes