J'utilise ce style pour changer fond couleur de ma Button
:
<style name="AccentButton" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@color/colorAccent</item>
<item name="Android:textColor">@color/white</item>
</style>
Et dans layout :
<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"/>
Ça marche. Mais quand j'appelle setEnabled(false)
sur cette Button
, elle garde la même couleur. Comment puis-je gérer ce cas?
Vous n'utilisez pas le style Widget.AppCompat.Button.Colored
correctement. Vous utilisez un style parent (Widget.AppCompat.Button.Colored
), mais vous l'appliquez en tant que thème. Cela signifie effectivement que la partie Widget.AppCompat.Button.Colored
est entièrement ignorée et que vous ne faites que changer la couleur par défaut du bouton (ce qui fonctionne, mais ne gère pas le cas désactivé).
À la place, vous devez utiliser une variable ThemeOverlay
et appliquer le style Colored
séparément:
<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"/>
Comme mentionné dans cette réponse sur l'utilisation du style Widget.AppCompat.Button.Colored
, la couleur désactivée est contrôlée par colorButtonNormal
et la couleur activée est contrôlée par colorAccent
. En utilisant le ThemeOverlay.AppCompat.Dark
, la textColor
devient automatiquement sombre, ce qui signifie que vous n'avez peut-être pas besoin de la ThemeOverlay
personnalisée.
En combinant la solution acceptée avec un widget personnalisé, nous pouvons avoir un bouton qui semble désactivé en définissant l'alpha. Cela devrait fonctionner pour toute combinaison de couleur de bouton et de texte:
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);
}
}
au lieu d'utiliser la couleur pour votre bouton, vous devriez utiliser un fond avec des sélecteurs. Voici le code de démonstration
<?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>
Lorsque vous avez changé par programme, vous devez agir de la sorte:
button = new Button(new ContextThemeWrapper(ActiVityName.this, R.style.AccentButton));
OU
if (button.isEnabled())
button.getBackground().setColorFilter(Color.Black, PorterDuff.Mode.MULTIPLY);
else
button.getBackground().setColorFilter(null);
Actuellement, j'utilise les paramètres suivants pour 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/values/styles.xml
<style name="ColoredButton" parent="Widget.AppCompat.Button.Colored">
<item name="Android:textColor">@color/btn_text_color</item>
</style>
et
<Button
Android:id="@+id/button"
style="@style/ColoredButton"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="button" />
Solution complète allant de ianhanniballake 'answer et Joe Bowbeer ' commentaire:
/res/values/styles.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>
Et partout où vous utilisez le bouton:
<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"/>
Cela a fonctionné vraiment bien pour moi
L'implémentation en Kotlin de la réponse de @ meanman ci-dessus, l'ajustement de l'alpha est de loin le moyen le plus simple à suivre et tous mes effets d'entraînement au toucher fonctionnent toujours comme avant:
import Android.content.Context
import Android.support.v7.widget.AppCompatButton
import Android.util.AttributeSet
class FadedDisableButton : AppCompatButton {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun setEnabled(enabled: Boolean) {
alpha = when {
enabled -> 1.0f
else -> 0.5f
}
super.setEnabled(enabled)
}
}