android - 支持较低操作系统版本的 VectorDrawables
问题描述
我正在开发一个项目,其中矢量可绘制对象与 ImageViews 一起用于具有android:src属性的图标。现在我们使用vectorDrawables.useSupportLibrary = true使用支持库来支持矢量绘图。它适用于棒棒糖以上的版本。因此,对于较低版本的支持,我需要将android:src更改为app:srcCompat。
但是这个项目很大,并且包含了带有android:src属性 allover 的 Imageviews。要一个一个地改变它是乏味的。有没有办法在一个地方进行修改而不修改每个图像视图。
我们的 CustomImageView 类扩展了 AppCompatImageView 。
<CustomImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/ic_call_circle"/>
我尝试编写 CustomBinding Adapter 但它仍然崩溃
@BindingAdapter("android:src")
public static void bingImageSrc(ImageView imageView, Integer rs){
if(rs != null){
imageView.setImageResource(rs);
}
}
@BindingAdapter("android:src")
public static void bingImageSrc(CustomImageView imageView, Drawable rs){
if(rs != null){
imageView.setImageDrawable(rs);
}
}
任何其他帮助...编辑:添加毕加索以设置图像。
HomeActivity.java
public class HomeActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@BindingAdapter("android:src")
public static void bingImageSrc(CustomImageView imageView, Integer rs){
if(rs != null){
Picasso.with(imageView.getContext()).load(rs).into(imageView);
}
}
}
活动主页.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<com.gosemathraj.vectordrawablesforprelollipopversion.CustomImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/ic_call_circle"/>
</androidx.constraintlayout.widget.ConstraintLayout>
CustomImageView.java
public class CustomImageView extends AppCompatImageView {
public CustomImageView(Context context) {
super(context);
}
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
BaseApp.java
public class BaseApp extends Application {
@Override
public void onCreate() {
super.onCreate();
}
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
}
构建.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion "29.0.0"
defaultConfig {
applicationId "com.gosemathraj.vectordrawablesforprelollipopversion"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
}
例外 :
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gosemathraj.vectordrawablesforprelollipopversion/com.gosemathraj.vectordrawablesforprelollipopversion.HomeActivity}: android.view.InflateException: Binary XML file line #10: Error inflating class com.gosemathraj.vectordrawablesforprelollipopversion.CustomImageView
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class com.gosemathraj.vectordrawablesforprelollipopversion.CustomImageView
at android.view.LayoutInflater.createView(LayoutInflater.java:613)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.gosemathraj.vectordrawablesforprelollipopversion.HomeActivity.onCreate(HomeActivity.java:19)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at android.view.LayoutInflater.createView(LayoutInflater.java:587)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.gosemathraj.vectordrawablesforprelollipopversion.HomeActivity.onCreate(HomeActivity.java:19)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_call_circle.xml from drawable resource ID #0x7f060055
at android.content.res.Resources.loadDrawable(Resources.java:1958)
at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
at android.widget.ImageView.<init>(ImageView.java:120)
at androidx.appcompat.widget.AppCompatImageView.<init>(AppCompatImageView.java:72)
at androidx.appcompat.widget.AppCompatImageView.<init>(AppCompatImageView.java:68)
at com.gosemathraj.vectordrawablesforprelollipopversion.CustomImageView.<init>(CustomImageView.java:17)
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at android.view.LayoutInflater.createView(LayoutInflater.java:587)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.gosemathraj.vectordrawablesforprelollipopversion.HomeActivity.onCreate(HomeActivity.java:19)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #1: invalid drawable tag vector
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881)
at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
at android.content.res.Resources.loadDrawable(Resources.java:1955)
at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
at android.widget.ImageView.<init>(ImageView.java:120)
at androidx.appcompat.widget.AppCompatImageView.<init>(AppCompatImageView.java:72)
at androidx.appcompat.widget.AppCompatImageView.<init>(AppCompatImageView.java:68)
at com.gosemathraj.vectordrawablesforprelollipopversion.CustomImageView.<init>(CustomImageView.java:17)
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at android.view.LayoutInflater.createView(LayoutInflater.java:587)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.gosemathraj.vectordrawablesforprelollipopversion.HomeActivity.onCreate(HomeActivity.java:19)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
解决方案
您可以使用@BindingAdapter
编写自定义绑定适配器。dataBinding
在您的应用级别启用build.gradle
android {
//...
dataBinding {
enabled = true
}
}
创建您的自定义static
方法和@BindingAdapter
注释以使您的自定义BindingAdapter
.
在你的方法体内检查你的
public class BindingUtils {
@BindingAdapter("android:src")
public static void setCustomImageSrc(CustomImageView imageView, @DrawableRes int drawable) {
//your implementation
}
}
编辑
像这样包装你的布局<layout>
并设置 src android:src="@{R.drawable.ic_call_circle}
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<import type="com.your.package.R" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<com.gosemathraj.vectordrawablesforprelollipopversion.CustomImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@{R.drawable.ic_call_circle}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
推荐阅读
- android - 如何在循环中连续从 Firebase 获取数据,如果数据不正确,应退出循环
- amazon-web-services - AWS CloudWatch 触发器在开始时间重复到结束时间
- node.js - Express 中间件问题(与 MongoDB 交互) - POST 方法的 req.body 未擦除空白并返回不可用对象错误
- python-3.x - matplotlib 轴的“rect”参数中的两个第一个坐标是什么?
- arrays - 从点数组返回所有三角形的最快方法
- android - 当点击 fcm 通知时,不要去特定的活动投入意图
- c# - 如何使用 FirebaseDatabase.Net 在实时数据库中创建电子邮件密钥
- mysql - 启用软删除时如何通过书架硬删除
- rest - 从 REST /entries 端点返回完整条目还是仅返回每个条目的 id 和标题?
- svm - 如何绘制支持向量回归的支持向量?