Lollipop的backgroundTint对Button没有影响

时间:2015-01-02 00:00:29

标签: android android-layout tint

我的活动中有一个按钮,我希望它具有我主题的强调色。 我自然不想使用新的backgroundTint属性来制作我自己的绘图,就像我们不得不做前Lollipop一样。

<Button
    android:id="@+id/btnAddCode"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:backgroundTint="@color/accent"
    android:text="@string/addressInfo_edit_addCode" />

不幸的是它没有效果,按钮保持灰色。

我为backgroundTintMode尝试了不同的值,这些值没有任何改变。

我也试过在我的Activity中以编程方式进行,它没有改变任何东西。

addCodeView.findViewById(R.id.btnAddCode).setBackgroundTintList(
     getResources().getColorStateList(R.color.accent));

为什么忽略我的色调?

编辑: 为了澄清,我确实在Lollipop设备上进行了测试。 其他小部件(例如EditText)可以正确自动着色。

14 个答案:

答案 0 :(得分:111)

坏消息

正如BoD所说,在Lollipop 5.0(API级别21)中为Button的背景着色毫无意义。

好消息

Lollipop 5.1(API级别22)似乎通过更改btn_mtrl_default_shape.xml(以及其他文件)修复了此问题:https://android.googlesource.com/platform/frameworks/base/+/6dfa60f33ca6018959ebff1efde82db7d2aed1e3%5E!/#F0

好消息

新支持库(版本22.1+)adds backward-compatible tinting support包含许多组件,包括AppCompatButton

不幸的是,android:backgroundTint属性仍然无效(可能我做错了) - 因此您必须使用{{3}在代码中设置ColorStateList }}。很高兴看到将来支持android:backgroundTint更新:Marcio Granzotto评论说app:backgroundTint适用于AppCompatButton!请注意,它是app:,而不是android:,因为它位于应用/库中。

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <AppCompatButton
        android:id="@+id/mybutton"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="Testing, testing"
        app:backgroundTint="#ff00ff"/>

</LinearLayout>

如果您将活动从AppCompatButton继承,您的活动会自动对Button而不是正常AppCompatActivity进行曝光。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AppCompatButton v = (AppCompatButton) findViewById(R.id.mybutton);
        ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{0xffffcc00});
        v.setSupportBackgroundTintList(csl);
    }
}

你当然应该从色彩资源中获取ColorStateList,但我很懒,所以......

哦,不要忘记将您的应用主题基于其中一个Theme.AppCompat主题,否则compat视图会非常非常悲伤......;)< /子>

这适用于2.3.7(Gingerbread MR1)和5.0(Lollipop&#39; Classic&#39;)。

答案 1 :(得分:29)

似乎对波纹绘制着色是没有意义的(按钮的默认背景是可绘制的波纹)。

事实上,在查看平台的默认按钮drawable之后,我发现&#34;正确&#34;这样做的方式:你必须在你的主题中定义它:

    <item name="android:colorButtonNormal">@color/accent</item>

(当然这仅适用于21 +级。)

警告:由于这是在主题中定义的,因此这将使用所有按钮的给定颜色(至少使用该主题的活动中的所有按钮。)

作为奖励,您还可以通过定义:

来更改波纹颜色
    <item name="android:colorControlHighlight">@color/accent_ripple</item>

答案 2 :(得分:22)

要解决与Android 5.0.x上的着色相关的问题,我使用以下内容:

createUI(...)

它仅对API 21使用支持方法,对所有其他情况使用ViewCompat。

答案 3 :(得分:19)

只需使用app:backgroundTint代替android:backgroundTint,色彩将在Lollipop下生效。原因是AppCompatActivity使用AppCompatViewInflater自动将Button或TextView更改为AppCompatButton或AppCompatTextView,然后app:backgroundTint生效。

enter image description here

In my project I used it, it worked.

答案 4 :(得分:11)

通过API 27在API 19上测试

<?xml version="1.0" encoding="utf-8"?>
  <android.support.v7.widget.AppCompatButton 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/retry"
    android:textColor="@android:color/white"
    app:backgroundTint="@android:color/holo_red_dark" />

将输出生成为 -

enter image description here

答案 5 :(得分:9)

我认为您需要设置android:background才能使android:backgroundTint正常工作。

为了更准确,我的猜测是你不能backgroundTint来自材料主题的默认按钮背景,它被定义为RippleDrawable

答案 6 :(得分:3)

谷歌https://code.google.com/p/android/issues/detail?id=201873

报道了类似问题

但在发布Android支持库后,修订版23.2.1(2016年3月)此错误已解决。

问题:FloatingActionButton.setBackgroundTintList(@Nullable ColorStateList色调)不再更改背景颜色

将支持库更新为Android Support Library to 23.2.1

使用设计支持库(23.2.1) appcompatwidgets ,如下所示

Material Design for Pre-Lollipop Devices

  

AppCompat(又名ActionBarCompat)最初是作为后端的   适用于在Gingerbread上运行的设备的Android 4.0 ActionBar API,   在反向移植的实现之上提供公共API层   和框架实施。 AppCompat v21提供API和   与Android 5.0同步的功能集

Android Support Library 22.1

  

使用AppCompat时自动着色小部件的能力是   非常有助于保持强大的品牌和一致性   整个应用程序。这在充气布局时自动完成    - 用AppCompatButton替换Button,用AppCompatTextView替换TextView等,以确保每个都支持着色。在   这个版本,那些色彩感知的小部件现在公开可用,   即使您需要子类化,也可以保持着色支持   支持的小部件。

答案 7 :(得分:2)

如果我们查看支持库的源代码,我们会看到它通常是已知的按钮,但如果我们改变按钮的形状(我有圆形按钮),色调不起作用确定在api&lt; = 21。 我们还可以看到TintManager成为公共类(appcompat-v7:23.1.1),因此我们可以从当前主题的默认按钮形状(在5.0中标记为OK)中获取ColorStateList(因此我们不必创建颜色数组):

    Context c = ...; // activity
    AppCompatButton ab = ...; // your button
    // works ok in 22+:
    if (Build.VERSION.SDK_INT <= 21) {
        // default appcompat button, that is tinted ok with current theme colors "abc_btn_default_mtrl_shape":
        // ColorStateList tint = TintManager.get(c).getTintList(R.drawable.abc_btn_default_mtrl_shape);
        // Appcompat 23.2 change:
        ColorStateList tint = AppCompatDrawableManager.get().getTintList(c, R.drawable.abc_btn_default_mtrl_shape);
        ab.setSupportBackgroundTintList(tint);
        }

答案 8 :(得分:1)

只需使用app:backgroundTint而不是android:backgroundTint

答案 9 :(得分:0)

因为属性backgroundTint仅用于API级别21及更高级别

答案 10 :(得分:0)

请注意recyclelerview最新更新的lib也会导致此错误。

此命令

  sendBtnView.setBackgroundTintList(colorState)

过去工作得很好,但不再为我工作了。在研究之后,事实证明原因是被加入gradle依赖关系的lib:

  compile 'com.android.support:recyclerview-v7:+'

所以我尝试将其更改为23.02.1,因为这是在Amit Vaghela帖子中推荐的。 我改为

  compile  'com.android.support:recyclerview-v7:23.02.1'

但gradle错误表示recyclerview lib没有此版本(23.02.1)(gradle无法在Jcenter raw.github或repo中找到它)。

然后,因为我知道setBackgroundTintList命令在过去使用版本22.02.0'时很好地解决了我在gradle依赖项中的所有其他库。 所以我把它改成:

compile   'com.android.support:recyclerview-v7:22.02.0'

现在再次运作。

答案 11 :(得分:0)

我不确定是否推荐这个,但你可以试试这个:

Drawable newDrawable = mBtnAction.getBackground();  // obtain Bg drawable from the button as a new drawable
DrawableCompat.setTint(newDrawable, mActivity.getHomeTobBarBGColor());  //set it's tint
mBtnAction.setBackground(newDrawable);  //apply back to button

一般来说,它有效。尝试ViewCompat,但似乎无法正常工作。

答案 12 :(得分:0)

您可以在backgroundTint版本中使用<android.support.design.button.MaterialButton "com.android.support:design:28.0.0-rc01"

答案 13 :(得分:0)

如果您使用的是androidx,则在android 5.1上同时添加了带前缀和不带前缀的版本已解决问题:

<style name="Button_Primary">
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:backgroundTint">@color/button_primary_selector</item>
    <item name="backgroundTint">@color/button_primary_selector</item><!--needed for android 5-->
</style>

button_primary选择器位于color文件夹中,具有以下内容:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:local="http://schemas.android.com/apk/res-auto">
    <item android:state_enabled="true" android:color="@android:color/holo_blue_dark" />
    <item android:state_enabled="false" android:color="@android:color/darker_gray" />
</selector>

并将其应用于AppCompatActivity上的常规按钮

<Button style="@style/Button_Primary"/>