SDK20及以下版本中使用Selector为ImageView设置Tint的兼容问题
Got it, let's break down why this is happening and how to fix it quickly. The crash occurs because using a StateListDrawable (like your bg_selector_image) directly with android:tint in XML isn't supported on Android SDK 20 and older. The android:tint attribute for ImageView only added support for drawable state lists starting in API 21. Newer versions handle this natively, but older ones throw an inflation error when they can't parse the tint drawable.
Here are two solid solutions to fix this:
Solution 1: Use AppCompatImageView with app:tint (Recommended)
The easiest way is to leverage the AppCompat library's built-in compatibility. It handles tint state lists smoothly even on older SDK versions.
- Ensure your project already has the AppCompat dependency (most modern Android projects do by default).
- Replace your regular
ImageViewwithAppCompatImageViewin the layout. - Swap
android:tintwithapp:tint, and add theappnamespace to your root layout.
Example updated layout:
<RelativeLayout ... android:background="@drawable/bg_selector" android:clickable="true" xmlns:app="http://schemas.android.com/apk/res-auto"> <!-- Add this namespace --> <androidx.appcompat.widget.AppCompatImageView ... android:src="@drawable/image__bank" app:tint="@drawable/bg_selector_image"/> <!-- Use app:tint instead of android:tint --> ... </RelativeLayout>
Note: If you're using the old support library instead of AndroidX, use android.support.v7.widget.AppCompatImageView instead.
Solution 2: Manually Set Tint List via Code
If you prefer not to use AppCompat, you can manually load the state list drawable and apply it as a ColorStateList in your activity/fragment code.
Kotlin Example:
val yourRelativeLayout = findViewById<RelativeLayout>(R.id.your_rel_layout_id) val imageView = findViewById<ImageView>(R.id.your_image_view_id) // Load the state list drawable and convert it to a ColorStateList val tintDrawable = resources.getDrawable(R.drawable.bg_selector_image) as StateListDrawable val colorStateList = ColorStateList(tintDrawable.stateSpecs, tintDrawable.colors) imageView.imageTintList = colorStateList // Sync the ImageView's pressed state with the parent RelativeLayout yourRelativeLayout.setOnClickListener { // Handle your click logic here imageView.isPressed = yourRelativeLayout.isPressed }
Java Example:
RelativeLayout yourRelativeLayout = findViewById(R.id.your_rel_layout_id); ImageView imageView = findViewById(R.id.your_image_view_id); // Load the state list drawable and convert it to a ColorStateList StateListDrawable tintDrawable = (StateListDrawable) getResources().getDrawable(R.drawable.bg_selector_image); ColorStateList colorStateList = new ColorStateList(tintDrawable.getStateSpecs(), tintDrawable.getColors()); imageView.setImageTintList(colorStateList); // Sync the ImageView's pressed state with the parent RelativeLayout yourRelativeLayout.setOnClickListener(v -> { // Handle your click logic here imageView.setPressed(yourRelativeLayout.isPressed()); });
Solution 1 is far more maintainable since AppCompat handles all the state syncing and compatibility edge cases for you.
内容的提问来源于stack exchange,提问作者Andrei Herford

