首页 > 解决方案 > ?Android < API21 的属性/颜色

问题描述

我的应用程序有多个根据用户偏好应用的主题,该应用程序在 Android API => 21 上运行良好,并且在较低版本中崩溃,我想支持 API 19 及更高版本,因此需要您的帮助。

Attrs.xml 三个自定义属性定义如下:

<resources>
        <declare-styleable name="da">
            <attr name="backgroundcolor" format="reference"/>
            <attr name="titletextcolor" format="reference"/>
            <attr name="textcolor" format="reference"/>
        </declare-styleable>
    </resources>

Styles.xml 包含自定义属性的三个自定义主题定义如下:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
            <item name="backgroundcolor">@color/colorWhite</item>
            <item name="titletextcolor">@color/colorPrimary</item>
            <item name="textcolor">@color/colorBlack</item>
        </style>

        <style name="AppTheme1" parent="Theme.AppCompat.Light.DarkActionBar">
            <item name="colorPrimary">@color/colorPrimary1</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark1</item>
            <item name="colorAccent">@color/colorAccent1</item>
            <item name="backgroundcolor">@color/colorWhite</item>
            <item name="titletextcolor">@color/colorPrimary1</item>
            <item name="textcolor">@color/colorBla`</item>
        </style>

        <style name="AppTheme2" parent="Theme.AppCompat.Light.DarkActionBar">
            <item name="colorPrimary">@color/colorPrimary2</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark2</item>
            <item name="colorAccent">@color/colorAccent2</item>
            <item name="backgroundcolor">@color/colorWhite</item>
            <item name="titletextcolor">@color/colorPrimary2</item>
            <item name="textcolor">@color/colorBlack</item>
        </style>

activity_nav.xml 自定义属性在多个布局中使用,类似于下面的示例:

 <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:background="?attr/backgroundcolor"
    android:layoutDirection="rtl"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_nav"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="?attr/backgroundcolor"
        app:itemTextColor="?attr/colorPrimary"
        app:itemIconTint="?attr/colorPrimary"

        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_nav"
        app:menu="@menu/activity_nav_drawer" />

</android.support.v4.widget.DrawerLayout>

NavActivity.java 为 onCreate 调用用户主题首选项,如下所示:

 public class NavActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    SharedPreferences shared;
    ListView listView;
    ListViewAdapter adapter;

    ArrayList<Model> arrayList = new ArrayList<Model>();
    private int i;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        shared = getSharedPreferences("Setting", Context.MODE_PRIVATE);
        int myStyle = shared.getInt("myStyle",0);
        switch (myStyle){
            case 0:
                this.setTheme(R.style.NoActionBar);
                break;
            case 1:
                this.setTheme(R.style.NoActionBar1);
                break;
            case 2:
                this.setTheme(R.style.NoActionBar2);
                break;
            case 3:
                this.setTheme(R.style.NoActionBar3);
                break;
        }
        setContentView(R.layout.activity_nav);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        String [] title = getResources().getStringArray(R.array.titels);
        String [] desc = getResources().getStringArray(R.array.desc);
        int icon = R.drawable.icon;

        ListView listView = findViewById(R.id.listView);

        for (i =0 ; i<title.length; i++){
            Model modle = new Model(title[i],desc[i],icon);
            arrayList.add(modle);
        }

        adapter = new ListViewAdapter(this,arrayList);
        listView.setAdapter(adapter);


        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }
}

错误日志
应用程序在版本 => 21 上运行良好,在较低版本中崩溃并出现以下错误:

  E/AndroidRuntime: FATAL EXCEPTION: main
        Process: www.alitkaan2.com, PID: 3098
        java.lang.RuntimeException: Unable to start activity ComponentInfo{www.alitkaan2.com/www.alitkaan2.com.NavActivity}: android.view.InflateException: Binary XML file line #18: Error inflating class android.support.design.widget.NavigationView
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)
         Caused by: android.view.InflateException: Binary XML file line #18: Error inflating class android.support.design.widget.NavigationView
            at android.view.LayoutInflater.createView(LayoutInflater.java:621)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:756)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
            at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
            at www.alitkaan2.com.NavActivity.onCreate(NavActivity.java:52)
            at android.app.Activity.performCreate(Activity.java:5231)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
            at android.app.ActivityThread.access$800(ActivityThread.java:135) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:136) 
            at android.app.ActivityThread.main(ActivityThread.java:5017) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:515) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
            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:423)
            at android.view.LayoutInflater.createView(LayoutInflater.java:595)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697) 
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:756) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
            at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469) 
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140) 
            at www.alitkaan2.com.NavActivity.onCreate(NavActivity.java:52) 
            at android.app.Activity.performCreate(Activity.java:5231) 
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
            at android.app.ActivityThread.access$800(ActivityThread.java:135) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:136) 
            at android.app.ActivityThread.main(ActivityThread.java:5017) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:515) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
            at dalvik.system.NativeStart.main(Native Method) 
         Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>
            at android.view.LayoutInflater.createView(LayoutInflater.java:621)
            at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
            at android.view.LayoutInflater.onCreateView(LayoutInflater.java:670)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at android.support.design.internal.NavigationMenuPresenter.inflateHeaderView(NavigationMenuPresenter.java:207)
            at android.support.design.widget.NavigationView.inflateHeaderView(NavigationView.java:281)
            at android.support.design.widget.NavigationView.<init>(NavigationView.java:193)
            at android.support.design.widget.NavigationView.<init>(NavigationView.java:104)
            at java.lang.reflect.Constructor.constructNative(Native Method) 
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
            at android.view.LayoutInflater.createView(LayoutInflater.java:595) 
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697) 
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:756) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
            at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469) 
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140) 
            at www.alitkaan2.com.NavActivity.onCreate(NavActivity.java:52) 
            at android.app.Activity.performCreate(Activity.java:5231) 
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
            at android.app.ActivityThread.access$800(ActivityThread.java:135) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:136) 
            at android.app.ActivityThread.main(ActivityThread.java:5017) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:515) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
            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:423)
            at android.view.LayoutInflater.createView(LayoutInflater.java:595)
            at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) 
            at android.view.LayoutInflater.onCreateView(LayoutInflater.java:670) 
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:469) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
            at android.support.design.internal.NavigationMenuPresenter.inflateHeaderView(NavigationMenuPresenter.java:207) 
            at android.support.design.widget.NavigationView.inflateHeaderView(NavigationView.java:281) 
            at android.support.design.widget.NavigationView.<init>(NavigationView.java:193) 
            at android.support.design.widget.NavigationView.<init>(NavigationView.java:104) 
            at java.lang.reflect.Constructor.constructNative(Native Method) 
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
            at android.view.LayoutInflater.createView(LayoutInflater.java:595) 
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697) 
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:756) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
            at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469) 
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140) 
            at www.alitkaan2.com.NavActivity.onCreate(NavActivity.java:52) 
            at android.app.Activity.performCreate(Activity.java:5231) 
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
            at android.app.ActivityThread.access$800(ActivityThread.java:135) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:136) 
            at android.app.ActivityThread.main(ActivityThread.java:5017) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:515) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
            at dalvik.system.NativeStart.main(Native Method) 
         Caused by: android.content.res.Resources$NotFoundException: File res/drawable/side_nav_bar.xml from drawable resource ID #0x7f08008f
            at android.content.res.Resources.loadDrawable(Resources.java:2101)
            at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
            at android.view.View.<init>(View.java:3554)
            at android.view.ViewGroup.<init>(ViewGroup.java:470)
            at android.widget.LinearLayout.<init>(LinearLayout.java:176)
            at android.widget.LinearLayout.<init>(LinearLayout.java:172)
            at java.lang.reflect.Constructor.constructNative(Native Method) 
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
            at android.view.LayoutInflater.createView(LayoutInflater.java:595) 
            at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) 
            at android.view.LayoutInflater.onCreateView(LayoutInflater.java:670) 
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:469) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
            at android.support.design.internal.NavigationMenuPresenter.inflateHeaderView(NavigationMenuPresenter.java:207) 
            at android.support.design.widget.NavigationView.inflateHeaderView(NavigationView.java:281) 
            at android.support.design.widget.NavigationView.<init>(NavigationView.java:193) 
            at android.support.design.widget.NavigationView.<init>(NavigationView.java:104) 
            at java.lang.reflect.Constructor.constructNative(Native Method) 
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
            at android.view.LayoutInflater.createView(LayoutInflater.java:595) 
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697) 
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:756) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
            at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
            at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469) 
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140) 
            at www.alitkaan2.com.NavActivity.onCreate(NavActivity.java:52) 
            at android.app.Activity.performCreate(Activity.java:5231) 
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
            at android.app.ActivityThread.access$800(ActivityThread.java:135) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:136) 
            at android.app.ActivityThread.main(ActivityThread.java:5017) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:515) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
            at dalvik.system.NativeStart.main(Native Method) 
        Caused b
    Disconnected from the target VM, address: 'localhost:8628', transport: 'socket'

我想支持 API 19 及更高版本的 Android 版本,因此需要您的帮助。

标签: javaandroidandroid-layout

解决方案


问题是由于形状

不能在 < API 21 的形状中使用 ?attr

解决方案: 1. 在形状中使用 @color 而不是 ?attr 2. 根据需要创建不同颜色的相同形状。3. 在 attrs 中为形状添加属性 4. 将属性添加到主题并将其链接到形状

这适用于 API 19 及更高版本


推荐阅读