Ich benutze diesen style um background Farbe meiner Button
zu ändern:
<style name="AccentButton" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@color/colorAccent</item>
<item name="Android:textColor">@color/white</item>
</style>
Und in 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"/>
Es klappt. Wenn ich jedoch setEnabled(false)
für diese Button
-Datei anrufe, behält sie dieselbe Farbe. Wie kann ich diesen Fall handhaben?
Sie verwenden den Widget.AppCompat.Button.Colored
-Stil nicht korrekt. Sie verwenden einen übergeordneten Stil (Widget.AppCompat.Button.Colored
), wenden diesen jedoch als Design an. Dies bedeutet effektiv, dass der Widget.AppCompat.Button.Colored
-Teil vollständig ignoriert wird und Sie stattdessen lediglich die Standardfarbe der Schaltfläche ändern (was funktioniert, was aber nicht den deaktivierten Fall behandelt).
Verwenden Sie stattdessen eine ThemeOverlay
und wenden Sie den Colored
-Stil separat an:
<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"/>
Wie in diese Antwort bei Verwendung des Widget.AppCompat.Button.Colored
-Stils erwähnt, wird die deaktivierte Farbe von colorButtonNormal
und die aktivierte Farbe von colorAccent
gesteuert. Durch die Verwendung von ThemeOverlay.AppCompat.Dark
wird die textColor
automatisch in dunkel geändert, was bedeutet, dass Sie die benutzerdefinierte ThemeOverlay
möglicherweise gar nicht benötigen.
Wenn Sie die akzeptierte Lösung mit einem benutzerdefinierten Widget kombinieren, können Sie eine Schaltfläche anzeigen, die durch Einstellen des Alphas deaktiviert erscheint. Dies sollte für jede Tasten- und Textfarbenkombination funktionieren:
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);
}
}
anstatt Farbe für Ihre Schaltfläche zu verwenden, sollten Sie einen Hintergrund mit Selektoren verwenden. Hier ist der Demo-Code
<?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>
Wenn Sie sich programmatisch geändert haben, müssen Sie so handeln:
button = new Button(new ContextThemeWrapper(ActiVityName.this, R.style.AccentButton));
ODER
if (button.isEnabled())
button.getBackground().setColorFilter(Color.Black, PorterDuff.Mode.MULTIPLY);
else
button.getBackground().setColorFilter(null);
Derzeit verwende ich die folgenden Einstellungen für 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>
und
<Button
Android:id="@+id/button"
style="@style/ColoredButton"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="button" />
Komplette Lösung von ianhanniballake 'answer und Joe Bowbeer ' Kommentar:
/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>
Und wo auch immer Sie die Schaltfläche verwenden:
<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"/>
Das hat wirklich gut für mich funktioniert
Die Kotlin-Implementierung von @ meanmans Antwort oben, das Anpassen von Alpha ist bei weitem der einfachste Weg und alle meine Touch-Ripple-Effekte funktionieren weiterhin wie zuvor:
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)
}
}