支持VectorDrawables用于较低的OS版本

时间:2019-07-01 09:17:58

标签: android android-databinding android-vectordrawable

我正在一个项目中,其中矢量可绘制对象与ImageViews一起用于具有 android:src 属性的图标。现在我们使用 vectorDrawables.useSupportLibrary = true 将支持库用于矢量绘画,它适用于棒棒糖以上的版本。因此,对于较低版本的支持,我需要将 android:src 更改为 app:srcCompat

但是该项目非常庞大,并且包含具有 android:src 属性的Imageview。要逐一更改它是很乏味的。有没有一种方法可以在一处进行修改而无需修改每个imageview。

我们的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适配器,但仍然崩溃

@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);
        }
    }
}

activity_home.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);
    }
}

build.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) 

1 个答案:

答案 0 :(得分:0)

您可以使用@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>