77

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

<!-- 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>
4

13 回答 13

102

使用支持库 23.2,一直到 API v7 都提供了对 Vector Drawables 的真正支持。建议禁用以前版本的支持,它在构建时呈现 PNG,通过添加

// Gradle Plugin 2.0+
 android {
   defaultConfig {
     vectorDrawables.useSupportLibrary = true
    }
 }

build.gradle文件。

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

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

drawableLeft在 TextView 的属性等情况下也支持 Vector Drawable 。

来源:图书馆公告

但是,我仍然会推荐Iconics libraryAndroidSVG或其他字体图标或 SVG 解决方案来获得完整的 SVG 标准矢量支持。

于 2016-03-04T12:20:37.543 回答
97

VectorDrawable 通过支持库在棒棒糖之前得到支持,但使用它们的方式取决于您拥有的支持库的版本。它可能不适用于所有情况。

我已制作此图以提供帮助(对支持库 23.4.0 至 - 至少 - 25.1.0 有效)。

VectorDrawable 备忘单

于 2017-01-25T17:08:18.317 回答
44

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

android {  
   defaultConfig {  
     vectorDrawables.useSupportLibrary = true  
    }  
 }

在应用程序类中定义这个:

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

现在您可以使用app:srcCompat="@drawable/ic_add",但如果您尝试使用,android:background=否则android:drawableLeft=应用程序会因“错误充气”异常而崩溃。

我们可以ic_add_wrapped.xml为这个向量创建包装的drawable:

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

现在它可以与 drawableLeft 或 background 等任何属性一起使用。刚设置android:drawableLeft="@drawable/ic_add_wrapped.xml"。警告!这是一个变通的解决方案。所以你用它来承担风险。

于 2016-11-10T09:06:08.980 回答
31

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

我们也很高兴在 Android Studio 1.4 中为您的矢量资源提供向后兼容性。一旦你的 res/drawable 中有一个 vectorDrawable 图像,Gradle 插件将在构建期间自动为 API 级别 20 及以下生成光栅 PNG 图像。这意味着您只需要为您的应用项目更新和维护您的矢量资源,Android Studio 就可以处理图像转换过程。

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

于 2015-12-22T14:22:26.243 回答
20

如果您使用 android studio,则需要使用 android Support Repository 30+,如果使用 Eclipse,则需要 android support library 23.2.1+。

build.gradle如果使用 2.0+ 版本,请检查您的(项目)在您的build.gradle(应用程序)中添加以下代码

// Gradle Plugin 2.0+  
 android {  
   defaultConfig {  
     vectorDrawables.useSupportLibrary = true  
    }  
 }

并且:如果使用 1.5 版,请在您的build.gradle(应用程序)中添加以下内容

// 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"/>

drawableLeft在 TextView 的属性等情况下也支持 Vector Drawable 。但它对我来说 api 22+ 有效,我仍然不知道它如何适用于低 api。

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

  • 您不能android:background在 xml 或View.setBackgroundResource()函数中使用该属性。您需要使用View.setBackground().
  • 您不能在 StateListDrawable xml-s 或其他 xml drawable 中使用 svg-s,您必须以编程方式生成它们。
  • 如果有通知,您不能使用 svg-s。
于 2016-04-16T07:31:32.280 回答
19

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

icon = VectorDrawableCompat.create(resources, R.drawable.ic_map_black_24dp, null)
于 2016-12-19T11:33:44.730 回答
9

对于低版本兼容,

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

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

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

    <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);
    
于 2018-07-12T09:31:13.347 回答
4

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

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

于 2017-01-20T13:19:06.320 回答
2

您可以以编程方式使用 .. 设置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 );
于 2018-02-27T09:22:57.443 回答
2

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

android.enableAapt2=false 

在 gradle.properties 中

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

于 2017-07-25T01:10:00.013 回答
2

只是为了使@2Dee 的答案完整:

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

就我个人而言,我更喜欢 svg 而不是 xml 向量:

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

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

于 2015-12-28T16:26:46.703 回答
1

在 gradle default 和 AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)中设置vectorDrawables.useSupportLibrary = true后;在创建活动中

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

 textview.setCompoundDrawablesWithIntrinsicBounds(R.drawable.movie, 0, 0, 0);
于 2019-03-02T17:41:11.637 回答
0

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

vectorDrawables.useSupportLibrary = true

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

textview.setCompoundDrawablesWithIntrinsicBounds(R.drawable.movi​​e, 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);
}
  • 我希望,它会帮助某人。
于 2019-11-13T05:13:54.763 回答