Android 无法使用属性值扩充布局文件

Android can't inflate layout file with attrs values

我正在开发一款可以在夜间模式和白天模式之间切换的应用 我用值

创建了一个 attrs 文件
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="ds" >

        <attr name="backgroundcolor" format="color"/>
        <attr name="cardbackground" format="color"/>
        <attr name="textcolor" format="color"/>
        <attr name="tintcolor" format="color"/>
        <attr name="buttoncolor" format="color"/>

    </declare-styleable>

</resources>

我做了相应的两种样式,分别是白天模式和夜间模式

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- Base application theme. -->
    <!-- Light Mode -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#2196F3</item>
        <item name="colorPrimaryDark">#1976D2</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="backgroundcolor">#fcfcfc</item>
        <item name="cardbackground">#ffffff</item>
        <item name="textcolor">#808080</item>
        <item name="tintcolor">#000000</item>
        <item name="buttoncolor">#2196F3</item>
    </style>

    <!-- Dark Mode -->
    <style name="darktheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#212121</item>
        <item name="colorPrimaryDark">#000000</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="backgroundcolor">#303030</item>
        <item name="cardbackground">#424242</item>
        <item name="textcolor">#FFFFFF</item>
        <item name="tintcolor">#FFFFFF</item>
        <item name="buttoncolor">#2196F3</item>
    </style>

</resources>

并且我将 attrs 值添加到布局中以代替 backgroundtextColor属性,以便我可以在它们之间切换

这是布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:minHeight="500dp"
    android:layout_margin="5dp"
    android:layout_height="match_parent"
    android:background="?attr/backgroundcolor">

    <android.support.v7.widget.CardView
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        card_view:cardCornerRadius="7dp"
        card_view:contentPadding="10dp"
        android:background="?attr/cardbackground">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:background="?attr/backgroundcolor">
            <ImageView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:src="@drawable/images"
                android:scaleType="centerCrop"/>

            <TextView
                android:id="@+id/header"
                android:layout_width="wrap_content"
                android:padding="2dp"
                android:text="Hello"
                android:textColor="?attr/textcolor"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:textSize="18sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/mNews"
                android:layout_width="wrap_content"
                android:padding="2dp"
                android:layout_height="wrap_content"
                android:text="Asam"
                android:layout_marginTop="10dp"
                android:textSize="16sp"
                android:textStyle="italic"
                android:textColor="?attr/textcolor"/>
        </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

我正在实现一个 ViewPager,我在其中扩充布局文件,之前没有实现 attrs 它工作正常,但是当我现在使用 attrs布局 xml 文件中的值 使应用程序崩溃

这里是 Viewpager Adapter 我在其中扩充布局文件

    public class HorizontalPagerAdapter extends PagerAdapter {
    String mResources[] = {"spider man description", "Iron man description", "batman description", "superman description"};
    String mHeader[] = {"Spider-Man", "Iron Man", "BatMan", "Super Man"};
    int mImages[] = {R.drawable.images, R.drawable.ironman, R.drawable.batman, R.drawable.super_man};

    Context mContext;
    LayoutInflater mLayoutInflater;

    public HorizontalPagerAdapter(Context context) {
        mContext = context;
        mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return mResources.length;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((LinearLayout) object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View itemView = mLayoutInflater.inflate(R.layout.content_main, container, false);

        TextView newsHeader = (TextView) itemView.findViewById(R.id.header);
        TextView newsContent = (TextView) itemView.findViewById(R.id.mNews) ;
        ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);

        newsHeader.setText(mHeader[position]);
        newsContent.setText(mResources[position]);
        imageView.setImageResource(mImages[position]);

        container.addView(itemView);

        return itemView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((LinearLayout) object);
    }
}

所以当 运行 应用程序给我这个错误时

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.slimshady.newsreaderfinal, PID: 5440
    android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class <unknown>
    Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>
    Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
        at android.view.LayoutInflater.createView(LayoutInflater.java:647)
        at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
        at android.view.LayoutInflater.onCreateView(LayoutInflater.java:720)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:788)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at com.example.slimshady.newsreaderfinal.HorizontalPagerAdapter.instantiateItem(HorizontalPagerAdapter.java:40)
        at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1010)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1158)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1092)
        at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1622)
        at android.view.View.measure(View.java:22071)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
        at android.view.View.measure(View.java:22071)
        at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1119)
        at android.view.View.measure(View.java:22071)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
        at android.view.View.measure(View.java:22071)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
        at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:401)
        at android.view.View.measure(View.java:22071)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at android.view.View.measure(View.java:22071)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
        at android.view.View.measure(View.java:22071)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at com.android.internal.policy.DecorView.onMeasure(DecorView.java:724)
        at android.view.View.measure(View.java:22071)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2422)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1504)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1761)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1392)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 13: TypedValue{t=0x2/d=0x7f030036 a=-1}
        at android.content.res.TypedArray.getDrawableForDensity(TypedArray.java:944)
        at android.content.res.TypedArray.getDrawable(TypedArray.java:928)
        at android.view.View.<init>(View.java:4768)
        at android.view.ViewGroup.<init>(ViewGroup.java:597)
        at android.widget.LinearLayout.<init>(LinearLayout.java:234)
        at android.widget.LinearLayout.<init>(LinearLayout.java:230)
        at android.widget.LinearLayout.<init>(LinearLayout.java:226)
            ... 55 more
Application terminated.

我在这里做错了什么?在网上找不到合适的解决方案,所以我创建了这个帖子。

不要使用 styleables,在新的 values-night 目录中创建另一个 styles.xml 并制作另一个具有更改值的 AppTheme 副本。

Full guide

膨胀 View 时,相关属性和值是从 LayoutInflater 使用的 Context 上的 Theme 中提取的。在这种情况下,很明显传递给 HorizontalPagerAdapterContext 没有正确的 Theme,如 Failed to resolve attribute 消息所示。

当应用程序 Context 用于创建 UI 组件时,经常会发生这种情况。默认情况下,应用程序 Context 并没有真正附加 Theme,即使在清单的 <application> 元素上指定了 android:theme。这只是为 Activity 类.

设置默认值 Theme

通常,您只想将当前的 Activity 用作任何与 View 相关的 Context,事实上,这就是这里的解决方案。 Activity 将附加适当的 Theme,然后在 Adapter.

中扩充这些页面时,您的自定义属性将正确解析