是否有可能使用VectorDrawable在button和TextViews使用android:DrawableRight?

当我在textview或imageview中使用VectorDrawable资产时,当使用“android:DrawableRight”/“android:DrawableEnd”/“android:DrawableStart”/“android:DrawableLeft”时,运行时崩溃。

该应用程序将编译罚款没有任何警告。

我在用

  • Gradle 1.5
  • 支持库23.2('com.android.support:appcompat-v7:23.2.0')

我发现,虽然是我可以编程方式分配SVG的Java没有这样的崩溃。

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

(我怀疑这是23.2的支持库错误。)

但有没有可能使用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); } } 

以下是来自Google材料devise网站的未经修改的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的膨胀错误。)

 03-02 07:56:08.808 13863-13863/? E/AndroidRuntime: FATAL EXCEPTION: main 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) 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:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) 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) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 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) 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:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) 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) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 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) 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:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 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: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) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 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) 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:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) 

因为Google很快就不会对这个问题做任何事情,所以我不得不为我的所有应用程序提供一个更可靠的可重用解决scheme:

  1. 首先在您的应用“res / values / attrs.xml”的 attrs.xml文件中添加自定义的TextView属性:

     <resources> <declare-styleable name="CustomTextView"> <attr name="drawableLeftCompat" format="reference"/> <attr name="drawableRightCompat" format="reference"/> <attr name="drawableTopCompat" format="reference"/> <attr name="drawableBottomCompat" format="reference"/> </declare-styleable> </resources> 
  2. 然后像这样创build自定义的TextView类:

     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 drawableLeft = null; Drawable drawableRight = null; Drawable drawableBottom = null; Drawable drawableTop = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { drawableLeft = attributeArray.getDrawable(R.styleable.CustomTextView_drawableLeftCompat); drawableRight = attributeArray.getDrawable(R.styleable.CustomTextView_drawableRightCompat); drawableBottom = attributeArray.getDrawable(R.styleable.CustomTextView_drawableBottomCompat); drawableTop = attributeArray.getDrawable(R.styleable.CustomTextView_drawableTopCompat); } else { final int drawableLeftId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableLeftCompat, -1); final int drawableRightId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableRightCompat, -1); final int drawableBottomId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableBottomCompat, -1); final int drawableTopId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableTopCompat, -1); if (drawableLeftId != -1) drawableLeft = AppCompatResources.getDrawable(context, drawableLeftId); if (drawableRightId != -1) drawableRight = AppCompatResources.getDrawable(context, drawableRightId); if (drawableBottomId != -1) drawableBottom = AppCompatResources.getDrawable(context, drawableBottomId); if (drawableTopId != -1) drawableTop = AppCompatResources.getDrawable(context, drawableTopId); } setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom); attributeArray.recycle(); } } } 
  3. 现在,您可以通过自定义属性在任何布局中轻松使用它:

     <YOUR_VIEW_PACKAGE.CustomTextView android:id="@+id/edt_my_edit_text" android:layout_width="wrap_content" android:layout_height="wrap_content" app:drawableLeftCompat="@drawable/your_vector_drawable" <!-- vector drawable --> app:drawableRightCompat="@drawable/your_vector_drawable" <!-- vector drawable --> app:drawableTopCompat="@drawable/your_vector_drawable" <!-- vector drawable --> app:drawableBottomCompat="@drawable/your_vector_drawable" <!-- vector drawable --> /> 
    • 你可以用ButtonEditTextRadioButton做类似的事情,因为它们是从TextView派生的

希望这可以帮助 :)

这个解决scheme不再正确。 从23.3.0版本vector绘制只能通过应用程序加载:srcCompat或setImageResource()

尝试将您的vector绘制到层列表或select器中:

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

我发现的最好的方法是:

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

为了补充这里的一些答案: 你可以得到VectorDrawable作为drawableLeft (等),但它取决于支持库版本,它带有一个价格。

在哪些情况下工作? 我已经使这个图帮助(有效的支持库23.4.0至less – 25.1.0)。

VectorDrawable作弊表

从Google:从Android支持库23.3.0开始,支持vector绘图只能通过app:srcCompat或setImageResource()加载。

http://android-developers.blogspot.ru/2016/02/android-support-library-232.html

没有其他答案的工作,这里是我如何添加一个VectorDrawable到一个TextView ,你应该使用VectorDrawableCompat.create()处理Android L VectorDrawables

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

简短,甜蜜,并重点!

如果你正在使用绑定,还有另外一种神奇的方法来在TextView中使用向量。 包装他们就像:

 android:drawableLeft="@{@drawable/vector_ic_access_time_24px}" android:drawableStart="@{@drawable/vector_ic_access_time_24px}" 

这将奇迹般的工作,我还没有调查幕后发生了什么,但我猜TextView是使用AppCompatResources或类似的getDrawable方法。

可以直接在xml中设置vector绘图,但是你必须包含数据绑定框架。

写吧

 <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 } } } 

您不必使用绑定库的任何其他function

编辑:

当然,如果你想使用vector绘制前的棒棒糖,你必须启用支持vector绘制使用

vectorDrawables.useSupportLibrary = true

所以你的build.gradle需要2个新的命令:

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

感谢rkmax的评论

我迟迟没有回答这个问题,因为我迟到了这个问题。 我有同样的问题与SVG /vector绘图与TextView。 而不是使自己的自定义绘制我能够解决我的问题,如下所示的两行代码:

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

希望它能帮助你。

我为此devise了一个小型库 – textview-rich-drawable (它也支持定义复合drawable的大小和着色)。

 <com.tolstykh.textviewrichdrawable.TextViewRichDrawable android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Some text" app:compoundDrawableHeight="24dp" app:compoundDrawableWidth="24dp" app:drawableTopVector="@drawable/some_vector_drawble" app:drawableEndVector="@drawable/another_vector_drawable" app:drawableTint="@color/colorAccent" /> 

和依赖

 compile 'com.tolstykh.textviewrichdrawable:textview-rich-drawable:0.3.2' 

在这里输入图像说明