如何使用 AppCompat 设置按钮的禁用颜色?
How do I set the disabled color of a button with AppCompat?
我用这个样式来改变我Button
的背景颜色:
<style name="AccentButton" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@color/colorAccent</item>
<item name="android:textColor">@color/white</item>
</style>
在布局中:
<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"/>
有效。但是当我在这个 Button
上调用 setEnabled(false)
时,它保持相同的颜色。我该如何处理这种情况?
您不应为按钮使用颜色,而应使用带有选择器的背景。这是演示代码
<?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>
当您以编程方式进行更改时,您需要这样做:
button = new Button(new ContextThemeWrapper(ActiVityName.this, R.style.AccentButton));
或
if (button.isEnabled())
button.getBackground().setColorFilter(Color.Black, PorterDuff.Mode.MULTIPLY);
else
button.getBackground().setColorFilter(null);
您没有正确使用 Widget.AppCompat.Button.Colored
样式。您正在使用父样式 (Widget.AppCompat.Button.Colored
),但将其用作主题。这实际上意味着 Widget.AppCompat.Button.Colored
部分被完全忽略,而您只是更改按钮的默认颜色(有效,但不处理禁用的情况)。
相反,您应该使用 ThemeOverlay
并单独应用 Colored
样式:
<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"/>
如this answer on using the Widget.AppCompat.Button.Colored
style所述,禁用颜色由colorButtonNormal
控制,启用颜色由colorAccent
控制。通过使用 ThemeOverlay.AppCompat.Dark
,textColor
会自动变为深色,这意味着您可能根本不需要自定义 ThemeOverlay
。
将已接受的解决方案与自定义小部件相结合,我们可以通过设置 alpha 使按钮显示为禁用状态。这适用于任何按钮和文本颜色组合:
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);
}
}
目前,我为 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>
和
<Button
android:id="@+id/button"
style="@style/ColoredButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button" />
从 ianhanniballake' answer and Joe Bowbeer 评论扩展的完整解决方案:
/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>
无论你在哪里使用按钮:
<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"/>
这对我来说非常好
上面@meanman 的回答的 Kotlin 实现,调整 alpha 是迄今为止最简单的方法,我所有的触摸波纹效果仍然像以前一样工作:
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)
}
}
我用这个样式来改变我Button
的背景颜色:
<style name="AccentButton" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@color/colorAccent</item>
<item name="android:textColor">@color/white</item>
</style>
在布局中:
<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"/>
有效。但是当我在这个 Button
上调用 setEnabled(false)
时,它保持相同的颜色。我该如何处理这种情况?
您不应为按钮使用颜色,而应使用带有选择器的背景。这是演示代码
<?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>
当您以编程方式进行更改时,您需要这样做:
button = new Button(new ContextThemeWrapper(ActiVityName.this, R.style.AccentButton));
或
if (button.isEnabled())
button.getBackground().setColorFilter(Color.Black, PorterDuff.Mode.MULTIPLY);
else
button.getBackground().setColorFilter(null);
您没有正确使用 Widget.AppCompat.Button.Colored
样式。您正在使用父样式 (Widget.AppCompat.Button.Colored
),但将其用作主题。这实际上意味着 Widget.AppCompat.Button.Colored
部分被完全忽略,而您只是更改按钮的默认颜色(有效,但不处理禁用的情况)。
相反,您应该使用 ThemeOverlay
并单独应用 Colored
样式:
<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"/>
如this answer on using the Widget.AppCompat.Button.Colored
style所述,禁用颜色由colorButtonNormal
控制,启用颜色由colorAccent
控制。通过使用 ThemeOverlay.AppCompat.Dark
,textColor
会自动变为深色,这意味着您可能根本不需要自定义 ThemeOverlay
。
将已接受的解决方案与自定义小部件相结合,我们可以通过设置 alpha 使按钮显示为禁用状态。这适用于任何按钮和文本颜色组合:
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);
}
}
目前,我为 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>
和
<Button
android:id="@+id/button"
style="@style/ColoredButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button" />
从 ianhanniballake' answer and Joe Bowbeer 评论扩展的完整解决方案:
/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>
无论你在哪里使用按钮:
<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"/>
这对我来说非常好
上面@meanman 的回答的 Kotlin 实现,调整 alpha 是迄今为止最简单的方法,我所有的触摸波纹效果仍然像以前一样工作:
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)
}
}