棒棒糖的backgroundTint对button没有影响
我在我的活动中有一个button,我想它有我的主题的口音颜色。 自然,我想使用新的backgroundTint
属性,而不是像我们必须做的棒棒糖一样制作自己的drawable。
<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" />
不幸的是它没有效果,button保持灰色。
我为backgroundTintMode
尝试了不同的值,这并没有改变任何东西。
我也尝试在我的活动中以编程方式进行,这并没有改变任何东西。
addCodeView.findViewById(R.id.btnAddCode).setBackgroundTintList( getResources().getColorStateList(R.color.accent));
为什么我的色彩被忽略?
编辑:只是为了澄清,我确实在棒棒糖设备上testing。 其他小部件(如EditText)正确自动着色。
坏消息
就像BoD说的那样,在Lollipop 5.0(API level 21)中调整Button的背景是没有意义的。
好消息
棒棒糖5.1(API级别22)似乎通过更改btn_mtrl_default_shape.xml(以及其他文件)来解决此问题: https ://android.googlesource.com/platform/frameworks/base/+/6dfa60f33ca6018959ebff1efde82db7d2aed1e3%5E!/#F0
好消息
新的支持库(版本22.1+)向许多组件添加了向后兼容的着色支持 ,包括AppCompatButton !
不幸的是, android:backgroundTint
属性仍然不起作用(也许我做错了什么) – 所以你必须在代码中设置ColorStateList
,使用setSupportBackgroundTintList()
。 将来看到支持android:backgroundTint
会非常好。 更新 :Marcio Granzotto评论说, app:backgroundTint
适用于AppCompatButton! 请注意,它是app:
android:
而不是android:
因为它在app / library中。
<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>
如果让它从AppCompatActivity
inheritance,您的活动将自动使AppCompatButton
充气,而不是正常的Button
。
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(姜饼MR1)和5.0(棒棒糖的“经典”)都有效。
看起来,绘制可绘制的波纹是没有意义的(并且button的默认背景是可绘制的波纹)。
实际上,在查看平台的默认button后,我find了“正确”的方法来做到这一点: 你必须在你的主题中定义这个:
<item name="android:colorButtonNormal">@color/accent</item>
(当然这只适用于21级以上)。
警告:由于这是在一个主题中定义的,所以将为所有button(至less是使用该主题的活动中的所有button)使用给定的颜色。
作为奖励,你也可以通过定义这个来改变波纹的颜色:
<item name="android:colorControlHighlight">@color/accent_ripple</item>
要解决与Android 5.0.x上着色有关的问题,我使用这样的东西:
public static void setButtonTint(Button button, ColorStateList tint) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP && button instanceof AppCompatButton) { ((AppCompatButton) button).setSupportBackgroundTintList(tint); } else { ViewCompat.setBackgroundTintList(button, tint); } }
它仅对API 21使用支持方法,对于其他所有情况使用ViewCompat。
只需使用app:backgroundTint
代替android:backgroundTint
,色彩将在棒棒糖下面生效。 原因是AppCompatActivity
使用AppCompatViewInflater
自动将Button或TextView更改为AppCompatButton或AppCompatTextView,然后app:backgroundTint
生效。
在我的项目中,我用它,它的工作。
我通常使用PorterDuffdynamic地执行它:
mbutton = (Button) findViewById(R.id.mybutton); mbutton.getBackground().setColorFilter(anycolor, PorterDuff.Mode.MULTIPLY);
你可以在这里查看不同的混合模式和很好的例子。
我认为你需要有android:background
设置使android:backgroundTint
工作。
为了更准确,我的猜测是,你不能backgroundTint
材质主题,这是定义为RippleDrawable
的默认button背景。
Google https://code.google.com/p/android/issues/detail?id=201873上报告了类似的问题;
但Android支持库发布之后,版本23.2.1 (2016年3月) 此错误已解决。
问题:FloatingActionButton.setBackgroundTintList(@Nullable ColorStateList tint)不再改变背景颜色
将支持库更新到Android Support Library to 23.2.1
使用devise支持库(23.2.1)和appcompatwidgets如下
预棒棒糖设备的材料devise :
AppCompat(又名ActionBarCompat)作为Gingerbread上运行的设备的Android 4.0 ActionBar API的后端开始,在后端实现和框架实现之上提供了一个通用的API层。 AppCompat v21提供了一个与Android 5.0最新的API和function集
Android支持库22.1 :
使用AppCompat时自动着色小部件的能力对于在整个应用程序中保持强大的品牌和一致性非常有帮助。 这是膨胀布局时自动完成的 – 用AppCompatButtonreplaceButton,用AppCompatTextViewreplaceTextView等,以确保每个都可以支持着色。 在这个版本中,那些色彩感知的小部件现在是公开的,允许你保持着色支持,即使你需要inheritance一个支持的小部件。
如果我们查看支持库的源代码,我们可以看到它通常是已知的button,但是如果我们改变button的形状(我有圆形button),色调在api <= 21中不起作用。 我们也可以看到TintManager成为公共类(appcompat-v7:23.1.1),所以我们可以从当前主题的默认button形状(在5.0中着色)中获取ColorStateList(所以我们不必创build数组颜色):
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); }
由于属性backgroundTint
仅用于API级别21和更高级别
请注意recyclerview最新的lib也会导致这个bug。
这个命令
sendBtnView.setBackgroundTintList(colorState)
过去完美的工作,但不要为我工作。 经过研究发现原因是被添加到gradle依赖的lib:
compile 'com.android.support:recyclerview-v7:+'
所以我试图把它改成23.02.1,就像在Amit Vaghela的post里推荐的那样。 我改变了
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'
现在它再次运作。
我不确定这是否被推荐,但你可以试试这个:
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
但它似乎并没有正常工作。