Api < 21的可拉伸着色

是否有可能为 api < 21制作可绘着色工作?

<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_calendar"
android:tint="@color/primary" />

工作正常,但只适用于具有 API21的设备。对于较低的 api 设备或 AppCompat 支持有什么解决方案吗?什么都找不到。

79257 次浏览

A similar question has been asked before here: https://stackoverflow.com/a/26533340/950427

Android Drawable Tinting is supported in Android 5.0+ (API 21+) only. (It does say "At the moment this is limited to coloring the action bar and some widgets.").

Theming

...

When you set these attributes, AppCompat automatically propagates their values to the framework attributes on API 21+. This automatically colors the status bar and Overview (Recents) task entry.

On older platforms, AppCompat emulates the color theming where possible. At the moment this is limited to coloring the action bar and some widgets.

And

Widget tinting

When running on devices with Android 5.0, all of the widgets are tinted using the color theme attributes we just talked about. There are two main features which allow this on Lollipop: drawable tinting, and referencing theme attributes (of the form ?attr/foo) in drawables.

AppCompat provides similar behaviour on earlier versions of Android for a subset of UI widgets:

Everything provided by AppCompat’s toolbar (action modes, etc) EditText Spinner CheckBox RadioButton Switch (use the new android.support.v7.widget.SwitchCompat) CheckedTextView You don’t need to do anything special to make these work, just use these controls in your layouts as usual and AppCompat will do the rest (with some caveats; see the FAQ below).

Sources:

http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html

https://chris.banes.me/2014/10/17/appcompat-v21/

Couldn't you simply use an ImageView to display your Drawable? android:tint works fine on older API levels.

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_calendar"
android:tint="@color/primary"
/>

Now AppCompatImageView,AppCompatButton will replace the ImageView,Button to support tint on devices with lower API. Check link for more details AppCompatImageView,AppCompatButton

Use the AppCompatImageView like so:

<android.support.v7.widget.AppCompatImageView
android:id="@+id/my_appcompat_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/my_image"
android:tint="#636363"
/>

Make sure you have the latest appcompat-v7 in your app's build.gradle.

Example: compile 'com.android.support:appcompat-v7:25.0.0' in your app's build.gradle.

For tinting images you could use imageView.setColorFilter(int color). This works from API 8 and worked for tinting my black image to a color I wanted. This can replace setImageTintList() but just using android:tint should also work.

You can achieve that using source code. Previously tinting was not supported by DrawableCompat. Starting from support library 22.1 you can do that, but you need do it in this way:

Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));

Use this NameSpace
xmlns:app="http://schemas.android.com/apk/res-auto"

and after you can replace every android:tint with app:tint. This fix the issue for me.

I'm a little late but here's how to do it.

val textInput = EditText(context)


val drawable = ContextCompat.getDrawable(context, R.drawable.your_drawable)
drawable?.let {
myDrawable -> DrawableCompat.setTint(myDrawable, ContextCompat.getColor(context, R.color.your_color))
textInput.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, myDrawable, null)
}

This will do as you want, and should work on all Android versions of the support library:

@JvmStatic
fun getTintedDrawable(inputDrawable: Drawable, @ColorInt color: Int): Drawable {
val wrapDrawable = DrawableCompat.wrap(inputDrawable.mutate())
DrawableCompat.setTint(wrapDrawable, color)
DrawableCompat.setTintMode(wrapDrawable, Mode.SRC_IN)
return wrapDrawable
}

If anyone want create new drawable (tin1,tint2..) try this

<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/your_image"
android:tint="@color/tint_color">
</bitmap>