Error inflating class Button in Android
Asked Answered
D

5

8

I have an application with min sdk 16 up to 23. I want to use Material design as much as possible. It also has to be fullscreen app. AppCompat support library is included. Now I have Logon activity with some buttons:

<Button
    android:id="@+id/act_logon_btn_logon"
    style="@style/ButtonDefault"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/act_logon_logon" />

Styles are as follows (values/styles.xml):

<style name="Theme.AppCompat.Light.NoActionBar.FullScreen" parent="@style/Theme.AppCompat.Light">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar.FullScreen"></style>

<style name="AppTheme" parent="AppThemeBase"></style>

<style name="ButtonDefault" parent="Widget.AppCompat.Button">
    <item name="android:textSize">?attr/font_medium</item>
</style>

<style name="FontStyle"></style>

<style name="FontStyle.Small">
    <item name="font_small">12sp</item>
    <item name="font_medium">14sp</item>
    <item name="font_large">16sp</item>
</style>

<style name="FontStyle.Medium">
    <item name="font_small">16sp</item>
    <item name="font_medium">18sp</item>
    <item name="font_large">20sp</item>
</style>

<style name="FontStyle.Large">
    <item name="font_small">20sp</item>
    <item name="font_medium">22sp</item>
    <item name="font_large">24sp</item>
</style>

And in values/attrs:

<declare-styleable name="FontStyle">
    <attr name="font_small" format="dimension" />
    <attr name="font_medium" format="dimension" />
    <attr name="font_large" format="dimension" />
</declare-styleable>

Attribute font_medium is defined as described here. The behavior I don't understand is that when the Logon activity gets opened, everything is OK, no exceptions. But when I open another activity from Logon activity with fragment inside and the fragment has a button with this style, I get an exception saying "Error inflating class Button". When I delete the textSize attribute from the ButtonDefault style, everything works. Why it does work somewhere and somewhere not? Is there something wrong with the custom attribute?

I've tried to create values-v21/styles.xml with that style but without effect.

Can you also please explain differences between following parent style definitions? I'm getting lost.

parent="Widget.AppCompat.Button"
parent="@style/Widget.AppCompat.Button"
parent="android:Widget.Button"
parent="android:Widget.AppCompat.Button"
parent="android:Widget.Material.Button"
parent="android:style/Widget.Material.Button"

Thank you.

EDIT 1 - exception:

12-17 10:56:53.950: E/AndroidRuntime(7251): FATAL EXCEPTION: main
12-17 10:56:53.950: E/AndroidRuntime(7251): Process: test.android, PID: 7251
12-17 10:56:53.950: E/AndroidRuntime(7251): java.lang.RuntimeException: Unable to start activity ComponentInfo{test.dci.android/test.dci.android.view.activity.TransactionActivity}: android.view.InflateException: Binary XML file line #49: Error inflating class Button
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2702)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.app.ActivityThread.access$900(ActivityThread.java:177)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.os.Handler.dispatchMessage(Handler.java:102)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.os.Looper.loop(Looper.java:145)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.app.ActivityThread.main(ActivityThread.java:5951)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at java.lang.reflect.Method.invoke(Native Method)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at java.lang.reflect.Method.invoke(Method.java:372)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
12-17 10:56:53.950: E/AndroidRuntime(7251): Caused by: android.view.InflateException: Binary XML file line #49: Error inflating class Button
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at test.dci.android.view.fragment.TransactionFragment.onCreateView(TransactionFragment.java:71)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1036)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1226)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1328)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2284)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:314)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at test.dci.android.view.activity.TransactionActivity.onCreateView(TransactionActivity.java:1)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:740)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at test.dci.android.view.activity.TransactionActivity.onCreate(TransactionActivity.java:31)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.app.Activity.performCreate(Activity.java:6289)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2655)
12-17 10:56:53.950: E/AndroidRuntime(7251):     ... 10 more
12-17 10:56:53.950: E/AndroidRuntime(7251): Caused by: java.lang.RuntimeException: Failed to resolve attribute at index 12
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.content.res.TypedArray.getDimensionPixelSize(TypedArray.java:582)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.widget.TextView.<init>(TextView.java:1400)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.widget.Button.<init>(Button.java:115)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.widget.Button.<init>(Button.java:108)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v7.widget.AppCompatButton.<init>(AppCompatButton.java:62)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v7.widget.AppCompatButton.<init>(AppCompatButton.java:58)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:98)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v7.app.AppCompatDelegateImplV7.createView(AppCompatDelegateImplV7.java:938)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:992)
12-17 10:56:53.950: E/AndroidRuntime(7251):     at 
Desirous answered 17/12, 2015 at 9:43 Comment(4)
can you post your errorHydroid
Done. The error occurs not only with buttons but also with edittexts - with style that contains the custom fontSize attributeDesirous
It seems that the exception android.view.InflateException: Binary XML file line #49: Error inflating class Button is caused by java.lang.RuntimeException: Failed to resolve attribute at index 12 It seems that the inflater is having issues recognizing ?attr/font_medium. Did you try changing that to a value, i.e.: 14sp, instead of removing textSize?Sec
If I change the textSize to specific value, as you said, it works.Desirous
D
1

Solved. The problem is that the attribute is uknown (or not specified) for the inflater. The solution is to define attribute values before inflating views that use the attribute.

Solution 1: The style with this attribute must be specified not only in the activity, but also in the fragment that has some views with this attribute. So add this line to fragment's onCreateView() before the line that inflates fragment's root view:

getContext().getTheme().applyStyle(fontStyleResId, true);

Solution 2: Set attributes value directly in application's theme:

<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar.FullScreen">
    <item name="font_small">@dimen/font_size_medium_small</item>
    <item name="font_medium">@dimen/font_size_medium_medium</item>
    <item name="font_large">@dimen/font_size_medium_large</item>
</style>
Desirous answered 13/1, 2016 at 0:3 Comment(0)
B
11

COPY your image files from "drawable-v24" folder to the "drawable" folder as well. Problem solved. credit: https://github.com/chrisjenx/Calligraphy/issues/417

Bluestocking answered 9/2, 2019 at 8:12 Comment(1)
This was my problem.Claviform
D
1

Solved. The problem is that the attribute is uknown (or not specified) for the inflater. The solution is to define attribute values before inflating views that use the attribute.

Solution 1: The style with this attribute must be specified not only in the activity, but also in the fragment that has some views with this attribute. So add this line to fragment's onCreateView() before the line that inflates fragment's root view:

getContext().getTheme().applyStyle(fontStyleResId, true);

Solution 2: Set attributes value directly in application's theme:

<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar.FullScreen">
    <item name="font_small">@dimen/font_size_medium_small</item>
    <item name="font_medium">@dimen/font_size_medium_medium</item>
    <item name="font_large">@dimen/font_size_medium_large</item>
</style>
Desirous answered 13/1, 2016 at 0:3 Comment(0)
L
1

I fixed it by creating own appcompat style for api less then 21,

styles.xml

  <style name="ColoredButtonAppcompat">
    <item name="android:textAppearance">@style/ButtonTextStyle</item>
    <item name="android:background">@drawable/colored_button_background</item>
    <item name="android:minHeight">48dip</item>
    <item name="android:minWidth">88dip</item>
    <item name="android:focusable">true</item>
    <item name="android:clickable">true</item>
    <item name="android:gravity">center_vertical|center_horizontal</item>
</style>

<style name="ButtonTextStyle" >
    <item name="android:textSize">14dp</item>
    <item name="android:textColor">@android:color/white</item>
</style>

styles-v21.xml

<style name="ColoredButtonAppcompat" parent="Widget.AppCompat.Button.Colored"/>

Leporine answered 3/3, 2016 at 9:29 Comment(0)
S
0

As we discussed in the comment section, the problem is that the inflater somehow fails to recognize ?attr/font_medium, thus raising an exception.

You can use the dimens.xml file to specify custom dimensions, like this:

<resources> 
    <dimen name="small">14sp</dimen>
    <dimen name="medium">16sp</dimen>
    <dimen name="large">18sp</dimen>
</resources>

and then in your styles.xml you refer to these values like this:

<style name="ButtonDefault" parent="Widget.AppCompat.Button">
    <item name="android:textSize">@dimen/medium</item>
</style>

As every other resource, dimens.xml can be placed in the according resource folders to accomodate to a specific device configuration (screen dimensions, density, language, etc.).

Sec answered 17/12, 2015 at 10:49 Comment(4)
I'm a little rusty with Android development, but I think you can't refer to other attributes when using <style> tags. <style> tags can only have explicit values (like 14sp) or a reference to an explicit value (like @dimen/medium --> 16sp)Sec
But in that case I am not able to use different font size across the app as user choice in Preference activity... Or how to combine it?Desirous
You can't set styles programmatically. You can allow the users to choose the preferred font and get the corresponding dimension from the dimens.xml file (remember that dimens.xml is a resource file). After that, you set the font size to your widgets.Sec
I can not? So far I was using the getTheme().applyStyle() method and it worked... And how can I do this programatically? The only thing I want is to be able to choose font size in preference activity, that's all.Desirous
M
0

I faced a similar situation while developing using Kotlin: In order to solve this issue, copy the app the content in drawable-24 to drawable. This is done to support older Android devices.

Medalist answered 14/7, 2020 at 23:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.