2

I am facing a weird issue when I try to assign a color to a TextView from an attribute in my styles.xml instead from the colors.xml.

So I have my styles.xml (excerpt) which defines the color for "color_title":

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="color_title" format="reference" />

    <style name="DayTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="color_title">@color/buttonHoverBackground</item>
    </style>

    <style name="NightTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="color_title">@color/buttonBackground</item>
    </style>

</resources>

If I use it in a normal layout, it works fine. But when I try to use it in a list item which is used in a custom array adapter to populate a ListView, I get an android.view.InflateException:

"Binary XML file line #XX: Error inflating class android.widget.TextView".

This works fine in the adapter:

<TextView
                    android:id="@+id/ticker_article_title"
                    android:layout_width="match_parent"
                    android:textColor="@color/black"
                    android:layout_height="wrap_content"
                    android:textSize="@dimen/news_detail_info_box_title"/>

This doesn't work

<TextView
               android:id="@+id/ticker_article_title"
               android:layout_width="match_parent"
               android:textColor="?attr/color_title"
               android:layout_height="wrap_content"
               android:textSize="@dimen/news_detail_info_box_title"/>

So I am wondering if this is normal or why I can't use style attributes in an ArrayAdapter while it still works in every other part of the app.

Edit: Here is the full stacktrace

E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.mycompany.myapp, PID: 20045
android.view.InflateException: Binary XML file line #96: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:633)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at de.mycompany.myapp.screens.adapter.NewsOverviewTickerAdapter.getView(NewsOverviewTickerAdapter.java:90)
at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
at android.widget.AbsListView.obtainView(AbsListView.java:2346)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
at android.widget.ListView.onMeasure(ListView.java:1182)
at android.view.View.measure(View.java:17429)
at android.widget.RelativeLayout.measureChild(RelativeLayout.java:697)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
at android.view.View.measure(View.java:17429)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1488)
at android.view.View.measure(View.java:17429)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17429)
at com.ryanharter.viewpager.ViewPager.onMeasure(ViewPager.java:1511)
at android.view.View.measure(View.java:17429)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17429)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:868)
at android.view.View.measure(View.java:17429)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463)
at android.view.View.measure(View.java:17429)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124)
at android.view.View.measure(View.java:17429)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17429)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17429)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17429)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2815)
at android.view.View.measure(View.java:17429)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:137

Line 13 in the stacktrace (de.mycompany.myapp.screens.adapter.NewsOverviewTickerAdapter.getView(NewsOverviewTickerAdapter.java:90)) points to this part in the custom ArrayAdapter:

if (rootView == null) {
    final LayoutInflater inflater = (LayoutInflater) getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    rootView = inflater.inflate(
            R.layout.fragment_newsoverview_ticker_listitem, null);
            ...

Edit2: Here is an example which shows the usage of ?attr/ in View and the ListView within the same layout file and fragment. The button uses android:textColor="?attr/color_settings_sublabels":

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/button_meine_ressorts"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:textSize="@dimen/news_detail_info_box_title"
            android:textColor="?attr/color_settings_sublabels"
            android:background="?attr/color_background"
            android:text="@string/menu_favorites_edit"
            android:textAllCaps="true"/>

        <include layout="@layout/load_data_shimmer"
                 android:id="@+id/loadingPanel_initial"/>

        <ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/news_ticker_list"/>

    </LinearLayout>

</RelativeLayout>
Alexander Hoffmann
  • 5,104
  • 3
  • 17
  • 23
  • I dont know the exact solution but it was not working in adapter – Pavya Mar 22 '16 at 10:32
  • There is a related answer in stack overflow.You can refer http://stackoverflow.com/questions/14360645/android-custom-attribute-for-textview – Karthik Mar 22 '16 at 10:34
  • @Karthik The linked question discusses the usage of custom attributes. I am trying to use textColor. Is this really related? – Alexander Hoffmann Mar 22 '16 at 10:37
  • @user3676184 So is this a general statement? Style attributes just don't work in adapters? – Alexander Hoffmann Mar 22 '16 at 10:38
  • Maybe, the problem is that `textColor` is requesting an `int` which it can parse into a color and you are passing a reference..? So you need custom attributes, like Karthik suggested. – yennsarah Mar 22 '16 at 10:40
  • 1
    Avoid `?attr` calling . – IntelliJ Amiya Mar 22 '16 at 10:42
  • @Amy Good thought. But then I would expect it to fail everywhere in my app. I use the exact same style attribute (same "color_title") in a different part and don't get a crash. It really only occurs in the layout which is used by the adapter. – Alexander Hoffmann Mar 22 '16 at 10:42
  • @IntelliJAmiya Using "android:textColor="color_title" " instead of "android:textColor="?attr/color_title" " causes a compilation error. I also already successfully use the reference with ?attr/ in another layout file. – Alexander Hoffmann Mar 22 '16 at 10:44
  • what `Context` are you passing to your `ArrayAdapter`? is it `getApplicationContext()`? – pskink Mar 22 '16 at 11:59
  • @pskink I pass it "getActivity()" – Alexander Hoffmann Mar 22 '16 at 12:26
  • Could you post the whole stack trace? – shhp Mar 22 '16 at 12:26
  • try just for testing use it in your Activity, not Fragment – pskink Mar 22 '16 at 12:32
  • @shhp Updated my post. It includes the stacktrace and the part of code it points to. – Alexander Hoffmann Mar 22 '16 at 12:35
  • Can you explain why you think `?attr/color_title` **should work**? – OneCricketeer Mar 22 '16 at 12:40
  • @cricket_007 I think it should work because I define a reference to the color with the name "color_title" in my styles.xml. And as I mentioned it works well in other layouts already. – Alexander Hoffmann Mar 22 '16 at 12:50
  • I only ask because you only said `@color/black` works and didn't show another layout with the attr value. Are you using your DayTheme or NightTheme in the activity with the adapter? – OneCricketeer Mar 22 '16 at 12:53
  • did you try `getContext` instead of `getActivity` ? – pskink Mar 22 '16 at 12:54
  • @pskink Trying to implement the adapter in an Activity will take some time in my app. However, I already use the attributes within the same fragment and context outside of the adapter. I'll include the layout which shows one of the current usages. – Alexander Hoffmann Mar 22 '16 at 12:55
  • 1
    this is basically the `Context` that cannot access your attribute: first try `getContext` instead of `getActivity` in your `Fragment`, if it still doesnt work, try `getBaseContext` – pskink Mar 22 '16 at 12:57
  • @cricket_007 I updated my post (Edit2). It shows now an example where I assign the textColor to a Button with '?attr/'. I already tried it with both themes. Unfortunately the same error appears. – Alexander Hoffmann Mar 22 '16 at 13:03
  • 2
    @pskink This is the solution. The Inflater I am using in my custom ArrayAdapter had the wrong context. Instead of using the context I provide in the Adapters constructor, I called 'getContext()' (see first edit above) to create a LayoutInflater. Using the provided context instead works fine. – Alexander Hoffmann Mar 22 '16 at 13:14
  • @AlexanderHoffmann ya it works. – Jithish P N Jun 07 '20 at 20:12

0 Answers0