Android: el botón personalizado se atasca "Presionado"

Creé un botón personalizado en mi aplicación de Android que tiene básicamente dos vistas diferentes. Hay una imagen para cuando no se presiona el botón y otra imagen para usar mientras se presiona. A continuación se muestra cómo implementé el botón y cómo responde al usuario.

private void registerListeners() {

    calcButton.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            calcButton.requestFocusFromTouch();
            calcButton.setImageResource(R.drawable.calc_button_pressed);
            return false;
        }
    });

    calcButton.setOnFocusChangeListener(new View.OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            calcButton.setImageResource(R.drawable.calc_button_not_pressed);
        }
    });

    calcButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {           
            mathCalculation();
            calcButton.setImageResource(R.drawable.calc_button_not_pressed);
        }
    });
}

Mi problema es que hay un "error" en el que si el usuario toca el botón y arrastra su figura fuera del botón, el botón permanece presionado. La única solución que he implementado anteriormente es "setOnFocusChangeListener", por lo que una vez que el usuario seleccione algo más, aparecerá una copia de seguridad.

Quiero tenerlo para que el botón vuelva a salir cuando el usuario arrastre la figura tocada del botón.

¡Todas las sugerencias son muy apreciadas!

Gracias,

preguntado el 16 de mayo de 11 a las 19:05

Ps ... si alguien quiere ver lo que está sucediendo en acción, simplemente busque myProfit en el mercado de Android. Será la única aplicación que aparecerá. -

4 Respuestas

No necesita escribir una clase de botón separada para obtener ese comportamiento, puede implementarlo a través de un xml dibujable. Tenga esto en su xml y configúrelo como fondo para su botón:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
      android:drawable="@drawable/calc_button_pressed" />
    <item android:drawable="@drawable/calc_button_not_pressed" />
</selector>

contestado el 16 de mayo de 11 a las 23:05

mmm. No tengo ni idea de cómo implementar eso. Comencé a desarrollar para Android hace aproximadamente un mes y todavía tengo mucho que aprender. ¿Cuándo y dónde implemento el xml dibujable? perdón por ser un novato. - KevinM

OK, descubrí cómo usarlo. Creé xml dibujable en la carpeta hdpi. Lo llamé calc_button y lo llamé en mi "setOnTouchListener". ¡Funcionó perfectamente! Aunque tengo una pregunta. ¿Necesito crear este mismo xml dibujable en las carpetas mdpi y ldpi? - KevinM

Hola Kevin, me alegro de que haya funcionado. No deberías necesitar hacer eso porque de acuerdo con developer.android.com/guide/topics/resources/localization.html que el drawable La carpeta de recursos es la única que puede obtener 'mágicamente' los recursos de las distintas carpetas sin tener que declarar los valores "predeterminados". De lo contrario, solo para estar seguro, puede colocar el xml que creó bajo el drawable carpeta y eliminarlo de drawable-hdpi. Lea el enlace de localización que le envié, explica las razones para usar las configuraciones para las diferentes carpetas de recursos. - Gligor

En su método onTouch, verifique la acción del evento.

  • Si es MotionEvent.ACTION_DOWN, proceda como lo hizo.
  • Si es ACTION_UP o ACTION_CANCEL, entonces llama calcButton.setImageResource(R.drawable.calc_button_not_pressed);

http://developer.android.com/reference/android/view/MotionEvent.html

contestado el 16 de mayo de 11 a las 23:05

Podrías usar onTouch. Entonces usa el ACTION_OUTSIDE que se dispara cuando los usuarios tocan se mueve fuera del límite de la vista.

Edición 1: para ser más específico:

OnTouchListener(MotionEvent e) {
   switch(e.getAction()) {
      case MotionEvent.ACTION_OUTSIDE: // switch the image if the button
    }
}

contestado el 16 de mayo de 11 a las 23:05

Es porque el evento de clic "ocurre" solo cuando se toca y la liberación de. Si tocas y te mueves afuera, eso no es un clic.

Para hacer lo que quieras, usa un StateListDrawable, está hecho solo para eso.

contestado el 16 de mayo de 11 a las 23:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.