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.
Don't use styleables, create another styles.xml in new values-night directory and make another copy of AppTheme with changed values.
Full guide
When inflating
View
s, the relevant attributes and values are pulled from theTheme
on theContext
used by theLayoutInflater
. In this case, it was apparent that theContext
passed to theHorizontalPagerAdapter
did not have the correctTheme
on it, as indicated by theFailed to resolve attribute
message.This will often happen when the application
Context
is used in creating UI components. The applicationContext
doesn't really have aTheme
attached to it, by default, even if one is specified as theandroid:theme
on the manifest's<application>
element. That simply serves to set a defaultTheme
for theActivity
classes.Normally, you just want to use the current
Activity
as theContext
for anythingView
-related, and, indeed, that was the solution here. TheActivity
will have the appropriateTheme
attached, and your custom attributes will then resolve correctly when inflating those pages in theAdapter
.