自定义视图

时间:2017-11-14 15:42:01

标签: android android-vectordrawable

我创建了一个带有图片图标的自定义视图,我将其初始化为:

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文件上。

2 个答案:

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