如何在Android API 小于21的情况下使用VectorDrawables?

How to use VectorDrawables in Android API lower than 21?

我正在做一个 Android 项目,我选择 <vector> 来显示图标,因为它具有自适应性和动态性,但是,我只能 运行 在设备上使用这个应用程序 运行ning Android,其中 API 21 或更高。我的问题是如何在较低的 Android 版本(即 API 14 或类似版本)上使用 <vector>。谢谢!

<!-- drawable/ic_android_debug_bridge.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="48dp"
    android:width="48dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path android:fillColor="@color/primaryColorDark"
        android:pathData="M15,9A1,1 0 0,1 14,8A1,1 0 0,1 15,7A1,1 0 0,1 16,8A1,1 `0 0,1 15,9M9,9A1,1 0 0,1 8,8A1,1 0 0,1 9,7A1,1 0 0,1 10,8A1,1 0 0,1 9,9M16.12,4.37L18.22,2.27L17.4,1.44L15.09,3.75C14.16,3.28 13.11,3 12,3C10.88,3 9.84,3.28 8.91,3.75L6.6,1.44L5.78,2.27L7.88,4.37C6.14,5.64 5,7.68 5,10V11H19V10C19,7.68 17.86,5.64 16.12,4.37M5,16C5,19.86 8.13,23 12,23A7,7 0 0,0 19,16V12H5V16Z" /></vector>

Vector Drawables 现在向后兼容,只需将您的 gradle 版本升级到 1.4.0-beta3 或更高版本,并升级您的 IDE :

We are also excited to offer backwards compatibility for your vector assets in Android Studio 1.4. Once you have a vectorDrawable image in your res/drawable, the Gradle plugin will automatically generate raster PNG images for API level 20 and below during build time. This means you only need to update and maintain your vector asset for your app project and Android Studio can take care of image conversion process.

http://android-developers.blogspot.com.uy/2015/09/android-studio-14.html

只是为了让@2Dee 的回答完整:

VectorDrawable 无法在 API 20 及更低版本上使用。官方的方法生成了png,然后变成了BitmapDrawables,打破了矢量图的思路。

我个人更喜欢 svg 而不是 xml 矢量:

  • 此类图形可以直接从 Illustrator 或其他流行软件中导出
  • svg 正确支持转换、文本、遮罩和其他东西
  • 所有平台上的真实可缩放矢量图形
  • 体积更小,构建速度更快

要使用矢量图形,您可以尝试 https://github.com/BigBadaboom/androidsvg。这是一个 svg reader 和 svg 兼容的 ImageView。

有了支持库 23.2,对 Vector Drawables 的真正支持已经一直提供到 API v7。 建议通过添加

来禁用在构建时呈现 PNG 的以前版本的支持
// Gradle Plugin 2.0+
 android {
   defaultConfig {
     vectorDrawables.useSupportLibrary = true
    }
 }

build.gradle 文件。

实现相当简单。只需在 Drawable 上使用新的 srcCompat 属性(在应用命名空间下!):

<ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  app:srcCompat="@drawable/ic_add" />    // <= this is new

在 TextView drawableLeft 属性.

等情况下也支持矢量绘图

来源:library announcement

但是,我仍然会推荐 Iconics library, AndroidSVG 之类的东西,或者其他字体图标或 SVG 解决方案以获得完整的 SVG 标准矢量支持。

如果你使用 android studio,你需要使用 android Support Repository 30+ 如果使用 Eclipse,需要 android 支持库 23.2.1+。

检查你的 build.gradle(项目)如果使用 2.0+ 版本,请在你的 build.gradle(应用程序)

中添加以下代码
// Gradle Plugin 2.0+  
 android {  
   defaultConfig {  
     vectorDrawables.useSupportLibrary = true  
    }  
 }

并且:如果使用 1.5 版,请在您的 build.gradle(app)

中添加以下内容
// Gradle Plugin 1.5  
 android {  
   defaultConfig {  
     generatedDensities = []  
  }  

  // This is handled for you by the 2.0+ Gradle Plugin  
  aaptOptions {  
    additionalParameters "--no-version-vectors"  
  }  
 }  

这里是使用矢量图标的示例代码:

<ImageView  
  android:layout_width="wrap_content"  
  android:layout_height="wrap_content"  
  app:srcCompat="@drawable/ic_add"
  tools:ignore="MissingPrefix" />

<ImageButton
  android:layout_width="wrap_content"
  android:background="@android:color/transparent"
  app:srcCompat="@drawable/camera"
  tools:ignore="MissingPrefix"
  android:layout_height="wrap_content"/>

在像 TextView 的 drawableLeft 属性 这样的情况下,也支持矢量绘图。但它对我有效api 22+,我仍然不知道它如何适用于低api。

如果你想在API 21以下兼容,请记住:

  • 您不能在 xml 或 View.setBackgroundResource() 函数中使用 android:background 属性。您需要使用 View.setBackground().
  • 您不能在 StateListDrawable xml-s 或其他 xml 绘图中使用 svg-s,您必须以编程方式生成它们。
  • 您不能在通知的情况下使用 svg-s。

我找到解决办法了!对于那些使用 TextView 和其他 "android" 命名空间属性搜索解决方案的人。 首先这是必要的:

android {  
   defaultConfig {  
     vectorDrawables.useSupportLibrary = true  
    }  
 }

并在应用程序 class 中定义:

    @Override
    public void onCreate() {
        super.onCreate();
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

现在您可以使用 app:srcCompat="@drawable/ic_add",但如果您尝试使用 android:background=android:drawableLeft=,应用程序将崩溃并出现 "Error inflating" 异常。

我们可以为这个向量创建包装的可绘制对象ic_add_wrapped.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_add"/>
</layer-list>

现在它可以与任何 属性 一起使用,例如 drawableLeft 或背景。只需设置 android:drawableLeft="@drawable/ic_add_wrapped.xml"。 警告!这是一个变通解决方案。所以您使用它需要您自担风险。

当您需要以编程方式添加 VectorDrawable(从 SVG 创建)时,您可以这样做:

icon = VectorDrawableCompat.create(resources, R.drawable.ic_map_black_24dp, null)

我遇到了一个问题,我的矢量图会显示出来,但会完全变黑,这是因为您无法在矢量 xml 文件中引用颜色资源。

因此,您必须使用实际颜色而不是 @color/primaryColorDark,例如#212121

通过支持库pre-Lollipop支持 VectorDrawable,但使用它们的方式取决于您拥有的支持库的版本。它可能并非在所有情况下都有效。

我已经 this diagram 提供帮助(对支持库 23.4.0 至 - 至少 - 25.1.0 有效)。

如果您使用的是 Android Studio 3.0.0,您可以设置

android.enableAapt2=false 

在 gradle.properties

https://www.reddit.com/r/androiddev/comments/6mj8di/android_studio_30_canary_6_released/

您可以通过编程方式使用 .. 将 drawableLeft 设置为您的 editTexttextView

喜欢

Drawable tick_drawable = VectorDrawableCompat.create(getResources(), R.drawable.green_tick, null);
    if (tick_drawable != null) {
        tick_drawable.setBounds(0, 0, tick_drawable.getIntrinsicWidth(),tick_drawable.getIntrinsicHeight());
    }

然后像这样向左绘制..

editText.setCompoundDrawables( tick_drawable , null, null, null );

为了低版本兼容,

  1. 在gradle中添加以下内容,

    android {  
       defaultConfig {  
         vectorDrawables.useSupportLibrary = true  
        }  
     }
    
  2. 在您的应用程序的 onCreate() 中添加以下代码 class,

    @Override
        public void onCreate() {
            super.onCreate();
            AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
        }
    
  3. 在 xml for imageView,

    <ImageView
        android:id="@+id/imageViewMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/transparent"
        app:srcCompat="@drawable/ic_success"/>
    
  4. 如果您想以编程方式更改图像源,请使用它,

    imageView.setImageResource(R.drawable.ic_launcher);
    

在 gradle 默认设置 vectorDrawables.useSupportLibrary = trueAppCompatDelegate.setCompatVectorFromResourcesEnabled(true) 后; 在 activity 中创建

为了避免 android:drawableleft 在 Textview 中崩溃,以编程方式将 drawble left 设置为 textview 例如:

 textview.setCompoundDrawablesWithIntrinsicBounds(R.drawable.movie, 0, 0, 0);

我也发现了同样的问题。我做到了:

vectorDrawables.useSupportLibrary = true

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

textview.setCompoundDrawablesWithIntrinsicBounds(R.drawable.movie, 0, 0, 0);

很好。但是在那之后,我得到了找不到资源的错误。
所以我发现还是根据SDK版本添加矢量图比较好

最后,这个解决方案对我来说很好:-

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    textview.setCompoundDrawablesWithIntrinsicBounds(null, null, AppCompatResources.getDrawable(this, R.drawable.movie), null);
} else {
    textview.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.movie, 0);
}
  • 希望对某人有所帮助。