使用android:DrawableRight在按钮和文本视图中是否可以使用VectorDrawable?

131

当我在TextView或ImageView中使用VectorDrawable资源并使用“android:DrawableRight”/“android:DrawableEnd”/“android:DrawableStart”/“android:DrawableLeft”时,会导致运行时崩溃。

应用程序将正常编译而没有任何警告。

我正在使用:

  • Gradle 1.5
  • Support Library 23.2('com.android.support:appcompat-v7:23.2.0')

然而,我发现我可以通过Java以编程方式分配SVG而不会出现此类崩溃。

TextView tv = (TextView) findViewById(R.id.textView);
tv.setCompoundDrawablesWithIntrinsicBounds(null,null, getResources().getDrawable(R.drawable.ic_accessible_white_36px),null);

我怀疑这是23.2版本的支持库bug。

但是,是否可以使用drawableRight等来处理SVG资源?

这是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="au.com.angryitguy.testsvg.MainActivity">


<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableRight="@drawable/ic_accessible_white_36px"
    android:background="@color/colorPrimary"
    android:textColor="#FFFFFF"
    android:textSize="22sp"
    android:text="Hello World!"/>
</RelativeLayout>

这是我的活动

package au.com.angryitguy.testsvg;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        }
    }

这是来自谷歌材料设计网站的未经修改的VectorDrawable资源。

<vector android:height="24dp" android:viewportHeight="24.0"
    android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FFFFFF" android:pathData="M12,4m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
    <path android:fillColor="#FFFFFF" android:pathData="M19,13v-2c-1.54,0.02 -3.09,-0.75 -4.07,-1.83l-1.29,-1.43c-0.17,-0.19 -0.38,-0.34 -0.61,-0.45 -0.01,0 -0.01,-0.01 -0.02,-0.01L13,7.28c-0.35,-0.2 -0.75,-0.3 -1.19,-0.26C10.76,7.11 10,8.04 10,9.09L10,15c0,1.1 0.9,2 2,2h5v5h2v-5.5c0,-1.1 -0.9,-2 -2,-2h-3v-3.45c1.29,1.07 3.25,1.94 5,1.95zM12.83,18c-0.41,1.16 -1.52,2 -2.83,2 -1.66,0 -3,-1.34 -3,-3 0,-1.31 0.84,-2.41 2,-2.83L9,12.1c-2.28,0.46 -4,2.48 -4,4.9 0,2.76 2.24,5 5,5 2.42,0 4.44,-1.72 4.9,-4h-2.07z"/>
</vector>

这是我的应用程序 build.gradle 文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "au.com.angryitguy.testsvg"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        // Stops the Gradle plugin’s automatic rasterization of vectors
        generatedDensities = []
    }
    // Flag to tell aapt to keep the attribute ids around
    aaptOptions {
        additionalParameters "--no-version-vectors"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.0'
}

这里是崩溃信息。(请注意与textview相关的inflate错误。)

java.lang.RuntimeException: Unable to start activity ComponentInfo{
    au.com.angryitguy.testsvg/au.com.angryitguy.testsvg.MainActivity}: 
    android.view.InflateException: Binary XML file line #13: 
    Error inflating class TextView

at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
...

Caused by: android.view.InflateException: 
    Binary XML file line #13: Error inflating class TextView
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
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 android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129)
at au.com.angryitguy.testsvg.MainActivity.onCreate(MainActivity.java:14)
at android.app.Activity.performCreate(Activity.java:5008)
...

Caused by: android.content.res.Resources$NotFoundException: 
    File res/drawable/ic_accessible_white_36px.xml from drawable resource ID #0x7f02004b
at android.content.res.Resources.loadDrawable(Resources.java:1918)
at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
at android.widget.TextView.<init>(TextView.java:622)
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:60)
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:56)
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:103)
at android.support.v7.app.AppCompatDelegateImplV7.createView(AppCompatDelegateImplV7.java:963)
at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:1022)
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:675)
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 android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129) 
at au.com.angryitguy.testsvg.MainActivity.onCreate(MainActivity.java:14) 
at android.app.Activity.performCreate(Activity.java:5008) 
...

Caused by: org.xmlpull.v1.XmlPullParserException:
    Binary XML file line #1: invalid drawable tag vector
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:877)
at android.graphics.drawable.Drawable.createFromXml(Drawable.java:818)
at android.content.res.Resources.loadDrawable(Resources.java:1915)
at android.content.res.TypedArray.getDrawable(TypedArray.java:601) 
at android.widget.TextView.<init>(TextView.java:622) 
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:60) 
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:56) 
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:103) 
at android.support.v7.app.AppCompatDelegateImplV7.createView(AppCompatDelegateImplV7.java:963) 
at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:1022) 
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44) 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:675) 
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 android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129) 
at au.com.angryitguy.testsvg.MainActivity.onCreate(MainActivity.java:14) 
at android.app.Activity.performCreate(Activity.java:5008) 
...

不行,因为SVG文件不受本地支持。你必须使用VectorDrawable代替(它只使用SVG规范的子集)。 - Phantômaxx
2
要了解如何使用VectorDrawable与drawableLeft、drawableRight、drawableTop和drawableBottom,请查看此答案 - Behzad Bahmanyar
我发现这对我有用:https://android.jlelse.eu/android-vector-drawables-on-pre-lollipop-crash-solution-45c0c34f0160 - Huy Tower
17个回答

207
可以使用drawableRight等来处理SVG资源吗?
是的。
现在,AppCompatTextView支持app:drawableLeftCompatapp:drawableTopCompatapp:drawableRightCompatapp:drawableBottomCompatapp:drawableStartCompatapp:drawableEndCompat复合绘图,支持后备绘图类型,如VectorDrawableCompat
请在您的gradle文件中包含此内容。
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'

在您的文本视图中,您可以使用
app:drawableLeftCompat
app:drawableStartCompat

如果您在使用按钮中的app:drawableLeftCompat、app:drawableStartCompat时遇到问题,您需要更新库至:

androidx.appcompat:appcompat:1.2.0-alpha01

他们遇到了一个错误

androidx.appcompat:appcompat:1.1.0-alpha01

你可以查看文档


如果您不想立即更新,那么:
因为谷歌似乎不会很快解决这个问题,我不得不想出一个更坚实、可重复使用的解决方案来处理我的所有应用程序:
  1. First add custom TextView attributes in attrs.xml file of your app "res/values/attrs.xml" :

    <resources>
        <declare-styleable name="CustomTextView">
            <attr name="drawableStartCompat" format="reference"/>
            <attr name="drawableEndCompat" format="reference"/>
            <attr name="drawableTopCompat" format="reference"/>
            <attr name="drawableBottomCompat" format="reference"/>
        </declare-styleable>
    </resources>
    
  2. Then create custom TextView class like this:

    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.drawable.Drawable;
    import android.os.Build;
    import android.support.v7.content.res.AppCompatResources;
    import android.support.v7.widget.AppCompatTextView;
    import android.util.AttributeSet;
    
    public class CustomTextView extends AppCompatTextView {
        public CustomTextView(Context context) {
            super(context);
        }    
        public CustomTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initAttrs(context, attrs);
        }
        public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initAttrs(context, attrs);
        }
    
        void initAttrs(Context context, AttributeSet attrs) {
            if (attrs != null) {
                TypedArray attributeArray = context.obtainStyledAttributes(
                        attrs,
                        R.styleable.CustomTextView);
    
                Drawable drawableStart = null;
                Drawable drawableEnd = null;
                Drawable drawableBottom = null;
                Drawable drawableTop = null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    drawableStart = attributeArray.getDrawable(R.styleable.CustomTextView_drawableStartCompat);
                    drawableEnd = attributeArray.getDrawable(R.styleable.CustomTextView_drawableEndCompat);
                    drawableBottom = attributeArray.getDrawable(R.styleable.CustomTextView_drawableBottomCompat);
                    drawableTop = attributeArray.getDrawable(R.styleable.CustomTextView_drawableTopCompat);
                } else {
                    final int drawableStartId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableStartCompat, -1);
                    final int drawableEndId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableEndCompat, -1);
                    final int drawableBottomId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableBottomCompat, -1);
                    final int drawableTopId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableTopCompat, -1);
    
                    if (drawableStartId != -1)
                        drawableStart = AppCompatResources.getDrawable(context, drawableStartId);
                    if (drawableEndId != -1)
                        drawableEnd = AppCompatResources.getDrawable(context, drawableEndId);
                    if (drawableBottomId != -1)
                        drawableBottom = AppCompatResources.getDrawable(context, drawableBottomId);
                    if (drawableTopId != -1)
                        drawableTop = AppCompatResources.getDrawable(context, drawableTopId);
                }
    
                // to support rtl
                setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, drawableTop, drawableEnd, drawableBottom);
                attributeArray.recycle();
            }
        }
    }
    
  3. Now you can use it easily in any layouts by your custom attributes:

    <YOUR_VIEW_PACKAGE.CustomTextView
        android:id="@+id/edt_my_edit_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:drawableStartCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
        app:drawableEndCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
        app:drawableTopCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
        app:drawableBottomCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
        />
    
  • 您可以对 ButtonEditTextRadioButton 进行类似的操作,因为它们都是从 TextView 派生而来。

4
非常有用的答案。无论如何,我建议您也阅读Dadou的非常完整的答案。从我的build.gradle中删除vectorDrawables { useSupportLibrary = true }就像那个答案建议的那样对我有用。 - Sam
我已经这样做了,现在我遇到了以下问题:当我在XML中附加onclick时,我会收到以下错误:java.lang.NoSuchMethodException: onClick [class android.view.View]。 - Ramdane Oualitsen
4
我不同意从 gradle 文件中删除 vectorDrawables useSupportLibrary = true 这行代码。当你删除它时,你仍然可以将向量图放在你的视图里,但它们会像 png 图片一样被拉伸并变得模糊。如果你希望 5.0/API21 以下的设备能正确地调整向量图大小,使其看起来清晰,你必须在 gradle 文件中使用该行代码。加入这一行会引发 IDE 查找您错误使用矢量图的区域,然后你必须通过 XML 中的 app:srcCompat 或者使用 VectorDrawableCompat.create() 来设置它。 - Heinous Games
如何添加 app:drawableEndCompat 以获得更好的RTL支持?因为 setCompoundDrawablesRelativeWithIntrinsicBounds 至少需要API级别17。 - Dr.jacky
1
设置可绘制对象的编程方式怎么样? - android developer
显示剩余5条评论

82

我发现最好的方法是:

Drawable leftDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_search);
search.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);

9
截至2017年8月25日,这是我唯一有效的解决方法(通过编程方式设置可绘制对象)。实际上,我使用了以下代码:Drawable drawable = VectorDrawableCompat.create(getResources(), status.getIconResId(), wrapper.getTheme()); statusButton.setCompoundDrawablesRelativeWithIntrinsicBounds(null, drawable, null, null); - saiyancoder
2
setCompoundDrawablesWithIntrinsicBoundsminSdk 版本为 17。否则,此功能运行良好。 - Victor Rendina
2
它的minSdk是1而不是17,你可能在寻找类似的API。setCompoundDrawablesWithIntrinsicBounds => minSdk 1; setCompoundDrawablesRelativeWithIntrinsicBounds => minSdk 17。 - 正宗白布鞋
编程中最佳的解决方案是通过编程方式进行设置,+1。 - Woton Sampaio
我将此与BindingAdapters一起使用,效果非常好,谢谢! - Ric17101
谢谢!是 setCompoundDrawablesWithIntrinsicBounds,不是 setCompoundDrawables - CoolMind

78

这个解决方案已经不正确了。从23.3.0版本开始,矢量图只能通过app:srcCompat或setImageResource()加载。

尝试将您的矢量图包装到layer-list或selector中:

<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableRight="@drawable/ic_accessible_white_wrapped"
    android:background="@color/colorPrimary"
    android:textColor="#FFFFFF"
    android:textSize="22sp"
    android:text="Hello World!"/>

ic_accessible_white_wrapped.xml:

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

这个很好用。谢谢。但是似乎你不能直接在“android:drawableXXXXX”中引用SVG,你需要将其包装在其他东西中。 - angryITguy
1
是的。你不能直接使用它。只能作为app:srcCompat或包装或以编程方式使用。这在这里已经描述了:http://android-developers.blogspot.ru/2016/02/android-support-library-232.html - Alexandr Shutko
啊..谢谢..我能看到你所指的段落。那么,如果他们告诉你不要这样做,这仍然是一个bug吗?;) - angryITguy
1
我认为这一切都与向后兼容有关。看起来存在一些问题,无法获得完整的SVG支持,因此他们做了一些变通处理... - Alexandr Shutko
没错,但按照你的方式,我必须创建两倍于我所有向量资源的数量。 - Behzad Bahmanyar
2
从支持版本23.3.0开始,@HarishGyanani已不再支持。您必须在您的活动中添加更多命令:static { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } } - Cuong Nguyen

64
为了补充之前的回答:您可以让VectorDrawable像drawableLeft一样工作(等等),但这取决于支持库版本,并且它有一个价格。 在哪些情况下有效? 我制作了此图表以帮助(适用于Support Library 23.4.0至少到25.1.0)。 VectorDrawable cheatsheet

2
这很棒,但是你应该在静态块中更正方法名称为setCompatVectorFromResourcesEnabled - Vikas Patidar
1
setCompatVectorFromResourcesEnabled解决方案在25.3.1上不起作用,不幸的是。 - Ilja S.
从23.3.0版本开始,只能通过使用app:srcCompat或setImageResource()来加载矢量可绘制对象,因此这种解决方案已被弃用且不再起作用。 - user25
启用 setCompatVectorFromSourcesEnabled(true) 可以在 Android 4.x 上加载矢量图形作为 android:background。非常感谢!(您需要将实际的矢量图形包装在单个项目的 layer-list 中) - Peterdk

15

没有其他答案有效,这是我如何将VectorDrawable添加到TextView中的方法,在处理低于Android LVectorDrawables时,你应该使用VectorDrawableCompat.create()

TextView titleTextView = (TextView) viewHolder.getView(android.R.id.text1);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
       Drawable leftDrawable = AppCompatResources
                            .getDrawable(context, R.drawable.ic_tickbox);
       titleTextView.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);
}
else
{
      //Safely create our VectorDrawable on pre-L android versions. 
       Drawable leftDrawable = VectorDrawableCompat
                            .create(context.getResources(), R.drawable.ic_tickbox, null);
       titleTextView.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);
}

简短、简洁,直戳要害!


这适用于Android P,最小API级别为26(目标28) - MiStr
@MiStr - 它也是向后兼容的 :) - Sakiboy

9

可以直接在xml中设置矢量图,但需要包含数据绑定框架。

只需编写

<TextView
...
android:drawableRight="@{@drawable/ic_accessible_white_36px}"/>

请在整个布局中添加一个 <layout> 标记,这样你的xml将如下所示:

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <RelativeLayout
        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"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="au.com.angryitguy.testsvg.MainActivity">


        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:drawableRight="@{@drawable/ic_accessible_white_36px}"
            android:text="Hello World!"
            android:textColor="#FFFFFF"
            android:textSize="22sp"/>
    </RelativeLayout>
</layout>

为了启用数据绑定框架,只需添加以下内容:

android {
    ....
    defaultConfig {
        dataBinding {
            enabled = true
        }
    }
}

您不必使用绑定库的其他功能

编辑:

当然,如果您想在Lollipop之前使用矢量图形,则需要使用以下命令启用支持矢量图形:

vectorDrawables.useSupportLibrary = true

因此,您的build.gradle需要添加两个新命令:

android {
    ....
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
        dataBinding {
            enabled = true
        }
    }
}

感谢rkmax提供的评论。


这是一个好主意,但是你需要编写一个绑定适配器来使其工作。这里有一个可用的示例:https://gist.github.com/lisawray/78c33f76809d2bcbbec9983e2c141a70 - BladeCoder
1
我必须说这对我很有效,但你必须在app/build.gradle中启用vectorDrawables.useSupportLibrary,并且在activity中添加AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)。 - rkmax
我忘了在build.gradle中添加defaultConfig,这可能是它不起作用的原因。 - Hans M
谢谢 - 你是救命恩人! - Van
这是一个被低估的答案! - DYS

9

1
暂时没有解决方案 - Shubham AgaRwal
尝试将您的矢量可绘制对象包装到图层列表或选择器中:<TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableRight="@drawable/ic_accessible_white_wrapped" android:background="@color/colorPrimary" android:textColor="#FFFFFF" android:textSize="22sp" android:text="Hello World!"/> ic_accessible_white_wrapped.xml:<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_accessible_white_36px"/> </layer-list> - Null Pointer Exception

6

我已经查看了所有的答案,使用最新版本的Android Studio 3.0.1和AppCompat Support Library 26.1.0,我可以保证这个程序可以正常运行。

build.gradle(app)文件中:

android {
    compileSdkVersion 26
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

dependencies {
    implementation 'com.android.support:appcompat-v7:26.1.0'
}

在扩展 AppcompatActivity 的活动中,包括这个静态代码块在外部方法中。
static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}  

如果您想将此应用于整个应用程序,只需在扩展Application类的类内包含这一行即可。
override fun onCreate() {
    super.onCreate()
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
}

在XML中使用TextView

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

<TextView
        android:id="@+id/passName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/account_drawableleft_selector"
        android:drawablePadding="5dp"
        android:ellipsize="marquee"
        android:fontFamily="@font/montserrat_light_family"
        android:gravity="center_vertical"
        android:marqueeRepeatLimit="marquee_forever"
        android:paddingRight="10dp"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:textColor="@color/app_text_color"
        android:textSize="12sp"
        tools:text="Account Name" />
</LinearLayout>

account_drawableleft_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_account_circle_24dp" /> <!-- checked -->
</selector>

在哪个API上运行良好?你试过19或20吗? - Divers
你能展示一下如何在XML中使用drawableRight来设置TextView吗? - Divers
2
就像上面的几位提到的那样,如果您直接将矢量 XML 用作 drawableLeft,仍会出现崩溃或异常,因此解决方法是将该矢量 XML 用作 TextView 的 drawableLeft 的选择器。用法可以在编辑后的答案中看到。 - Amit Tumkur
1
无法正常工作,您不能直接在xml中使用矢量可绘制对象来设置TextView。 - user25
在API 19和20中进行测试。我在应用程序类中使用了AppCompatDelegate.setCompatVectorFromResourcesEnabled。工作得非常好! - Red M
谢谢。在我的情况下,我必须写<layer-list xmlns:android="http://schemas.android.com/apk/res/android">而不是<selector …> - CoolMind

6

1
似乎这些属性不能与数据绑定一起使用? - Zijian Wang

5

很抱歉回答这个问题有些晚,因为我一直被这个问题困扰着。我遇到了与TextView相关的svg/vector drawables相同的问题。但是,我不需要制作自己的自定义drawable,只需使用以下两行代码即可解决我的问题:

Drawable drawableTop = AppCompatResources.getDrawable(view.getContext(), iconId);
view.setCompoundDrawablesWithIntrinsicBounds(null, drawableTop, null, null);

希望这能帮助到你。


不兼容早于 L 版本的设备。 - Sakiboy
@Sakiboy 是的,因为我正在使用最低API 17的代码。 - Rahul Sharma
在所有运行 pre-L 的设备上都无法使用 VectorDrawables,只是提醒一下。在使用此答案时要小心,因为有更安全、更准确的 API 可供使用。 - Sakiboy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接