2

I am working on an app that can switch between night mode and day mode i made an attrs file with the values

<?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>

and i made corresponding two styles that are for day mode and night mode respectively

<?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>

and i added the attrs values to the layout in place of background and textColor attributes so i can switch between them

Here is the Layout file

<?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>

I am implementing a ViewPager where i am inflating that layout file, previously without implementing the attrs it worked fine, but when i am now using the attrs values inside the layout xml file it is crashing the app

Here is the Viewpager Adapter where i am inflating the layout file

    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);
    }
}

So when running the app it is giving me this error

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.

What am i doing wrong here ? can't find the proper solution for this online so i am creating this thread.

4

2 回答 2

3

When inflating Views, the relevant attributes and values are pulled from the Theme on the Context used by the LayoutInflater. In this case, it was apparent that the Context passed to the HorizontalPagerAdapter did not have the correct Theme on it, as indicated by the Failed to resolve attribute message.

This will often happen when the application Context is used in creating UI components. The application Context doesn't really have a Theme attached to it, by default, even if one is specified as the android:theme on the manifest's <application> element. That simply serves to set a default Theme for the Activity classes.

Normally, you just want to use the current Activity as the Context for anything View-related, and, indeed, that was the solution here. The Activity will have the appropriate Theme attached, and your custom attributes will then resolve correctly when inflating those pages in the Adapter.

于 2019-04-20T09:36:20.983 回答
0

Don't use styleables, create another styles.xml in new values-night directory and make another copy of AppTheme with changed values.

Full guide

于 2019-04-19T20:21:44.190 回答