theme style studio colored buttons android appcompat android-button

style - text button android



¿Cómo configurar el color del botón deshabilitado con AppCompat? (6)

Actualmente, uso la siguiente configuración para Android API 15+.

/res/color/btn_text_color.xml

<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="#42000000" android:state_enabled="false" /> <item android:color="#ffffff" /> </selector>

/res/valores/estilos.xml

<style name="ColoredButton" parent="Widget.AppCompat.Button.Colored"> <item name="android:textColor">@color/btn_text_color</item> </style>

y

<Button android:id="@+id/button" style="@style/ColoredButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button" />

Yo uso este estilo para cambiar el color de fondo de mi Button :

<style name="AccentButton" parent="Widget.AppCompat.Button.Colored"> <item name="colorButtonNormal">@color/colorAccent</item> <item name="android:textColor">@color/white</item> </style>

Y en diseño :

<Button android:id="@+id/login_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/fragment_login_login_button" app:theme="@style/AccentButton"/>

Funciona. Pero cuando llamo a setEnabled(false) en este Button , mantiene el mismo color. ¿Cómo puedo manejar este caso?


Combinando la solución aceptada con un widget personalizado podemos tener un botón que aparece deshabilitado al configurar el alfa. Esto debería funcionar para cualquier combinación de botones y colores de texto:

public class ButtonWidget extends AppCompatButton { public ButtonWidget(Context context) { super(context); } public ButtonWidget(Context context, AttributeSet attrs) { super(context, attrs); } public ButtonWidget(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setEnabled(boolean enabled) { setAlpha(enabled ? 1 : 0.5f); super.setEnabled(enabled); } }


Cuando hayas cambiado programáticamente necesitas actuar de esa manera:

button = new Button(new ContextThemeWrapper(ActiVityName.this, R.style.AccentButton));

O

if (button.isEnabled()) button.getBackground().setColorFilter(Color.Black, PorterDuff.Mode.MULTIPLY); else button.getBackground().setColorFilter(null);


En lugar de usar color para su botón, debe usar un fondo con selectores. Aquí está el código de demostración

<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true"> <shape android:shape="rectangle"> <solid android:color="@color/yourEnabledColor" /> </shape> </item> <item android:state_enabled="false"> <shape android:shape="rectangle"> <solid android:color="@color/yourDisabledColor" /> </shape> </item> </selector>


No está utilizando el estilo Widget.AppCompat.Button.Colored correctamente. Estás usando un estilo principal ( Widget.AppCompat.Button.Colored ), pero aplicándolo como un tema. De hecho, esto significa que la parte Widget.AppCompat.Button.Colored se ignora por completo y en su lugar solo está cambiando el color predeterminado del botón (que funciona, pero no maneja el caso deshabilitado).

En su lugar, debe usar un ThemeOverlay y aplicar el estilo de Colored separado:

<style name="AccentButton" parent="ThemeOverlay.AppCompat.Dark"> <!-- customize colorButtonNormal for the disable color --> <!-- customize colorAccent for the enabled color --> </style> <Button android:id="@+id/login_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/fragment_login_login_button" android:theme="@style/AccentButton" style="@style/Widget.AppCompat.Button.Colored"/>

Como se mencionó en esta respuesta al usar el estilo Widget.AppCompat.Button.Colored , el color desactivado se controla mediante colorButtonNormal y el color habilitado se controla mediante colorAccent . Al usar el ThemeOverlay.AppCompat.Dark , el textColor se cambia automáticamente a oscuro, lo que significa que es posible que no necesite el ThemeOverlay personalizado en absoluto.


Solución completa que se extiende desde la respuesta de y el comentario de Joe Bowbeer :

/res/valores/estilos.xml

<style name="AccentButton" parent="ThemeOverlay.AppCompat.Dark"> <!-- customize colorAccent for the enabled color --> <!-- customize colorControlHighlight for the enabled/pressed color --> <!-- customize colorButtonNormal for the disabled color --> <item name="android:buttonStyle">@style/Widget.AppCompat.Button.Colored</item> </style>

Y donde quiera que uses el botón:

<Button android:id="@+id/login_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/fragment_login_login_button" android:theme="@style/AccentButton"/>

Eso funcionó muy bien para mí