Me gusta la sugerencia de filtro de color en respuestas anteriores de @conjugatedirection y @Tomasz; Sin embargo, descubrí que el código proporcionado hasta ahora no se aplicaba tan fácilmente como esperaba.
Primero, no se mencionó dónde aplicar y borrar el filtro de color. Es posible que haya otros buenos lugares para hacer esto, pero lo que me vino a la mente fue un OnTouchListener .
De mi lectura de la pregunta original, la solución ideal sería una que no involucrara ninguna imagen. La respuesta aceptada usando custom_button.xml de @emmby probablemente sea más adecuada que los filtros de color si ese es su objetivo. En mi caso, estoy comenzando con una imagen png de un diseñador de interfaz de usuario de cómo se supone que debe ser el botón. Si configuro el fondo del botón para esta imagen, la retroalimentación de resaltado predeterminada se pierde por completo. Este código reemplaza ese comportamiento con un efecto de oscurecimiento programático.
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 0x6D6D6D sets how much to darken - tweak as desired
setColorFilter(v, 0x6D6D6D);
break;
// remove the filter when moving off the button
// the same way a selector implementation would
case MotionEvent.ACTION_MOVE:
Rect r = new Rect();
v.getLocalVisibleRect(r);
if (!r.contains((int) event.getX(), (int) event.getY())) {
setColorFilter(v, null);
}
break;
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
setColorFilter(v, null);
break;
}
return false;
}
private void setColorFilter(View v, Integer filter) {
if (filter == null) v.getBackground().clearColorFilter();
else {
// To lighten instead of darken, try this:
// LightingColorFilter lighten = new LightingColorFilter(0xFFFFFF, filter);
LightingColorFilter darken = new LightingColorFilter(filter, 0x000000);
v.getBackground().setColorFilter(darken);
}
// required on Android 2.3.7 for filter change to take effect (but not on 4.0.4)
v.getBackground().invalidateSelf();
}
});
Extraje esto como una clase separada para la aplicación a múltiples botones, que se muestra como una clase interna anónima solo para entender la idea.