我创建了一个带有图片图标的自定义视图,我将其初始化为:
XML
IconFieldLinearLayout.java
private void initAttr(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.IconFieldLinearLayout, 0, 0);
Drawable icon = a.getDrawable(R.styleable.IconFieldLinearLayout_icon);
boolean tintIcon = a.getBoolean(R.styleable.IconFieldLinearLayout_tintIcon, true);
int color = a.getColor(R.styleable.IconFieldLinearLayout_tintColor, Color.WHITE);
a.recycle();
initIcon(context, icon, tintIcon, color);
} else {
initIcon(context, mDefaultDrawable, true, Color.WHITE);
}
}
当我使用这个drawable在Android 4.3上运行时:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#ffff"
android:pathData="M12,5.9c1.16,0 2.1,0.94 2.1,2.1s-0.94,2.1 -2.1,2.1S9.9,9.16 9.9,8s0.94,-2.1 2.1,-2.1m0,9c2.97,0 6.1,1.46 6.1,2.1v1.1L5.9,18.1L5.9,17c0,-0.64 3.13,-2.1 6.1,-2.1M12,4C9.79,4 8,5.79 8,8s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,13c-2.67,0 -8,1.34 -8,4v3h16v-3c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>
我明白了:
android.view.InflateException: Binary XML file line #0: Error inflating class tv.myapp.ui.iconfield.IconFieldLinearLayout
at android.view.LayoutInflater.createView(LayoutInflater.java:669)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:745)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:804)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:812)
at android.view.LayoutInflater.inflate(LayoutInflater.java:526)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at tv.myapp.base.view.BaseMosbyFragment.onCreateView(BaseMosbyFragment.java:34)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1984)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:626)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:540)
at tv.myapp.login.LoginActivity$1.lambda$setResource$1$LoginActivity$1(LoginActivity.java:70)
at tv.myapp.login.LoginActivity$1$$Lambda$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:177)
at android.app.ActivityThread.main(ActivityThread.java:5493)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1225)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1041)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at android.view.LayoutInflater.createView(LayoutInflater.java:643)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:745)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:804)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:812)
at android.view.LayoutInflater.inflate(LayoutInflater.java:526)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at tv.myapp.base.view.BaseMosbyFragment.onCreateView(BaseMosbyFragment.java:34)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1984)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:626)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:540)
at tv.myapp.login.LoginActivity$1.lambda$setResource$1$LoginActivity$1(LoginActivity.java:70)
at tv.myapp.login.LoginActivity$1$$Lambda$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:177)
at android.app.ActivityThread.main(ActivityThread.java:5493)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1225)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1041)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_person_outline.xml from drawable resource ID #0x7f0800db
at android.content.res.Resources.loadDrawable(Resources.java:2974)
at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
at tv.myapp.ui.iconfield.IconFieldLinearLayout.initAttr(IconFieldLinearLayout.java:59)
at tv.myapp.ui.iconfield.IconFieldLinearLayout.init(IconFieldLinearLayout.java:51)
at tv.myapp.ui.iconfield.IconFieldLinearLayout.<init>(IconFieldLinearLayout.java:34)
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at android.view.LayoutInflater.createView(LayoutInflater.java:643)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:745)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:804)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:812)
at android.view.LayoutInflater.inflate(LayoutInflater.java:526)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at tv.myapp.base.view.BaseMosbyFragment.onCreateView(BaseMosbyFragment.java:34)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1984)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:626)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:540)
at tv.myapp.login.LoginActivity$1.lambda$setResource$1$LoginActivity$1(LoginActivity.java:70)
at tv.myapp.login.LoginActivity$1$$Lambda$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:177)
at android.app.ActivityThread.main(ActivityThread.java:5493)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1225)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1041)
at dalvik.system.NativeStart.main(Native Method)
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #0: invalid drawable tag vector
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:933)
at android.graphics.drawable.Drawable.createFromXml(Drawable.java:873)
at android.content.res.Resources.loadDrawable(Resources.java:2970)
at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
at tv.myapp.ui.iconfield.IconFieldLinearLayout.initAttr(IconFieldLinearLayout.java:59)
at tv.myapp.ui.iconfield.IconFieldLinearLayout.init(IconFieldLinearLayout.java:51)
at tv.myapp.ui.iconfield.IconFieldLinearLayout.<init>(IconFieldLinearLayout.java:34)
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at android.view.LayoutInflater.createView(LayoutInflater.java:643)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:745)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:804)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:812)
at android.view.LayoutInflater.inflate(LayoutInflater.java:526)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at tv.myapp.base.view.BaseMosbyFragment.onCreateView(BaseMosbyFragment.java:34)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1984)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:626)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:540)
at tv.myapp.login.LoginActivity$1.lambda$setResource$1$LoginActivity$1(LoginActivity.java:70)
at tv.myapp.login.LoginActivity$1$$Lambda$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:177)
at android.app.ActivityThread.main(ActivityThread.java:5493)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1225)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1041)
at dalvik.system.NativeStart.main(Native Method)
我已将vectorDrawables.useSupportLibrary = true
放在我的gradle文件上。
答案 0 :(得分:4)
替换此行:
Drawable icon = a.getDrawable(R.styleable.IconFieldLinearLayout_icon);
用这些:
int iconId = a.getResourceId(R.styleable.IconFieldLinearLayout_icon, 0);
Drawable icon = AppCompatResources.getDrawable(context, iconId);
AppCompatResources
类将使用VectorDrawableCompat
创建drawable,如果资源是<vector>
并且平台足够大,以至于不能原生支持矢量绘图。
答案 1 :(得分:1)
public class MainActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
...
}
有关详细信息,请参阅此answer