app:srcCompat
的 ImageView
允许向后兼容使用矢量绘图。但除了View
之外,你如何将它们与其他ImageView
一起使用?例如,TextView
属性,例如android:drawableLeft
。
同时使用矢量drawable作为android:icon
MenuItem
导致崩溃,但出现以下异常:
Fatal Exception: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:626)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:702)
at android.view.LayoutInflater.inflate(LayoutInflater.java:470)
at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
at android.support.v7.view.menu.MenuItemImpl.setActionView(MenuItemImpl.java:621)
at android.support.v7.view.menu.MenuItemImpl.setActionView(MenuItemImpl.java:40)
at android.support.v4.view.MenuItemCompat.setActionView(MenuItemCompat.java:310)
at android.support.v7.view.SupportMenuInflater$MenuState.setItem(SupportMenuInflater.java:465)
at android.support.v7.view.SupportMenuInflater$MenuState.addItem(SupportMenuInflater.java:479)
at android.support.v7.view.SupportMenuInflater.parseMenu(SupportMenuInflater.java:196)
at android.support.v7.view.SupportMenuInflater.inflate(SupportMenuInflater.java:118)
at com.example.niceapp.context.main.MainActivity.onCreateOptionsMenu(MainActivity.java:101)
at android.app.Activity.onCreatePanelMenu(Activity.java:2578)
使用支持库23.2.0,如何解决此问题?
答案 0 :(得分:45)
更新2 :他们在支持库23.4.0中添加了再次启用它的选项:
对于AppCompat用户,我们添加了一个选择加入API,通过AppCompatDelegate.setCompatVectorFromResourcesEnabled()重新启用资源支持Vector Drawables(23.2中的行为) - 请记住,这仍然会导致内存问题更新配置实例的用法和问题,因此默认情况下禁用它。
<强>更新强>: 这不再适用于从版本23.3.0
开始对于AppCompat用户,我们决定删除其中的功能 让你使用前Lollipop设备上的资源中的矢量drawables 由于版本23.2.0 / 23.2.1中的实现中发现的问题 [https://code.google.com/p/android/issues/detail?id=205236,https://code.google.com/p/android/issues/detail?id=204708]。使用app:srcCompat 和setImageResource()继续工作。
来自Android Developers Google+ post
使用AppCompat和app:srcCompat是将矢量绘图集成到应用程序中最简单的方法。
该引用来自支持库版本23.2.0的官方blogpost。
该帖子还提到了以下内容:
您会发现直接引用
app:srcCompat
之外的矢量绘图将在Lollipop之前失败。但是,AppCompat
确实支持在另一个可绘制容器中引用向量drawable时加载它们,例如StateListDrawable
,InsetDrawable
,LayerDrawable
,LevelListDrawable
和{{ 1}}。通过使用此间接,您可以在RotateDrawable
的{{1}}属性的情况下使用向量drawable,这通常不能支持向量drawable。
这转换为以下步骤:
第1步:
创建或导入应用程序所需的矢量资源。例如,可以为搜索图标创建一个可绘制的矢量,并将其命名为TextView
第2步:
为先前创建的矢量drawable创建另一个代理可绘制资源。比方说,对于之前的android:drawableLeft
,ic_action_search_vector.xml
可以创建为简单的ic_action_search_vector.xml
,其中可能包含以下行:
ic_action_search.xml
如果您从另一个可绘制资源中引用了可绘制的矢量,则可以跳过此步骤。
第3步:
使用引用向量drawable(StateListDrawable
)而不是向量drawable的drawable资源(此处为<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_action_search_vector"/>
</selector>
)。对于菜单,它看起来像:
ic_action_search.xml
这是解决这个问题的方法!
答案 1 :(得分:29)
对于AppCompat版本23.3.0,其中没有通过选择器XML的工作解决方案(razzledazzle接受的答案)我们可以通过编程方式执行此操作:
activity_main.xml中
<android.support.v7.widget.AppCompatImageButton
android:id="@+id/btnEnter"
/>
MainActivity.java
AppCompatImageButton image = (AppCompatImageButton) findViewById(R.id.btnEnter);
if (image != null) {
VectorDrawableCompat vcAccept = VectorDrawableCompat.create(getResources(), R.drawable.vc_accept, getTheme());
VectorDrawableCompat vcAcceptWhite = VectorDrawableCompat.create(getResources(), R.drawable.vc_accept_white, getTheme());
StateListDrawable stateList = new StateListDrawable();
stateList.addState(new int[]{android.R.attr.state_focused, -android.R.attr.state_pressed}, vcAccept);
stateList.addState(new int[]{android.R.attr.state_focused, android.R.attr.state_pressed}, vcAcceptWhite);
stateList.addState(new int[]{-android.R.attr.state_focused, android.R.attr.state_pressed}, vcAcceptWhite);
stateList.addState(new int[]{}, vcAccept);
image.setImageDrawable(stateList);
}
此代码与此选择器xml相同:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/vc_accept" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/vc_accept_white" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/vc_accept_white" />
<item android:drawable="@drawable/vc_accept" />
</selector>
如果未使用API 23显示矢量drawable,则需要先将VectorDrawable
转换为常规Drawable
。如果你想使用setCompoundDrawablesWithIntrinsicBounds
,你需要这样做,但对于StateListDrawable我不需要。
Drawable icon;
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
icon = VectorDrawableCompat.create(getResources(), R.drawable.vc_icon, getContext().getTheme());
} else {
icon = getResources().getDrawable(R.drawable.vc_icon, getContext().getTheme());
}
答案 2 :(得分:15)
答案 3 :(得分:6)
您可以通过编程方式在TextView中添加Vector Drawable。利用 VectorDrawableCompat 来添加drawableLeft / drawableRight / drawableTop / drawableBottom / drawableStart / drawableEnd。
<强>步骤:强>
我。如果TextView在Activity:
中TextView tvUserName= (TextView)findViewById(R.id.et_username_or_email);
VectorDrawableCompat drawableCompat=VectorDrawableCompat.create(getResources(), R.drawable.layer_list_ic_user, tvUserName.getContext().getTheme());
tvUserName.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableCompat, null, null, null);
II。如果TextView在Fragment中:
TextView tvUserName= (TextView )view.findViewById(R.id.et_username_or_email);
VectorDrawableCompat drawableCompat=VectorDrawableCompat.create(getActivity().getResources(), R.drawable.layer_list_ic_user, tvUserName.getContext().getTheme());
tvUserName.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableCompat, null, null, null);
有关VectorDrawableCompat的更多信息,请参阅此link
答案 4 :(得分:1)
Android 5.0(API级别21)及更高版本提供了矢量绘图支持。如果您的应用具有较低的API级别,Vector Asset Studio会将矢量可绘制文件添加到您的项目中;此外,在构建时,Gradle以各种分辨率创建PNG光栅图像。 Gradle生成由build.gradle文件中的域特定语言(DSL)generatedDensities属性指定的PNG密度。要生成PNG,构建系统需要适用于Gradle 1.5.0或更高版本的Android插件。
如果您包含在您的gradle中,则情况并非如此 vectorDrawables.useSupportLibrary = true
设置为false或完全删除该行,所有向量都将按原样运行。但对于安卓版本的android,他们将能够依赖转换后的PNG
答案 5 :(得分:1)
表单android studio 3.0.0 android:src 不支持矢量图像,21以下我得到异常。使用 app:srcCompat 作为矢量图像。将所有矢量图像文件保留在 drawable 文件夹中。
<RelativeLayout
android:id="@+id/counterValuePanel"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_cart_notify"/>
</RelativeLayout>
在应用程序类中定义:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_cart_notify"/>
</layer-list>
现在您可以使用.xml文件了。不要忘记使用此链接: xmlns:app =&#34; http://schemas.android.com/apk/res-auto"
CREATE TRIGGER SubtractStock ON Receipt
FOR INSERT, UPDATE, DELETE
AS
UPDATE W
SET Stock = CASE
WHEN WarehouseID = 'ARM01' AND I.Quantity <= Stock THEN Stock - Quantity
WHEN WarehouseID = 'ARM01' AND I.Quantity > Stock THEN Stock - Quantity
WHEN WarehouseID = 'ARM02' THEN I.Quantity - Stock
END
FROM inserted I JOIN Warehouses W ON I.ItemID = W.ItemID
现在你可以使用app:srcCompat =&#34; @ drawable / ic_cart_notify&#34;但如果你尝试在android:background或android:drawableLeft中使用,那么你得到了#34;错误的膨胀&#34;例外。为此创建一个新的包装drawable .xml文件, ic_cart_notify 是矢量图标。
{{1}}
答案 6 :(得分:0)
server/controller
到您希望在Android 5以下版本的设备上使用VectorDrawables的每个活动。
答案 7 :(得分:0)
在android的textview中将矢量可绘制设置为侧面可绘制
AppCompatTextView now支持app:drawableLeftCompat
,app:drawableTopCompat
,app:drawableRightCompat
,app:drawableBottomCompat
,app:drawableStartCompat
和{{1 }}复合可绘制对象,支持向后移植的可绘制类型,例如 VectorDrawableCompat 。
将此内容添加到您的gradle文件中
app:drawableEndCompat
您可以在文本视图中使用
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
答案 8 :(得分:-1)
我使用新的支持库,我所要做的就是:
compile 'com.android.support:appcompat-v7:25.1.1'
在Build.gradle文件中
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
现在你使用像片段,活动或适配器一样使用它作为你班级的第一行
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
在使用之后就像我们之前一样,使用something.xml
<ImageView
android:id="@+id/ivMainNavigationIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Something.java
thumbIcon.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.ic_check_circle_black_24dp));
或者如果您需要动态设置可绘制ID
thumbIcon.setImageDrawable(ContextCompat.getDrawable(context,drawableID));