Android:自定义视图上的膨胀异常

Posted

技术标签:

【中文标题】Android:自定义视图上的膨胀异常【英文标题】:Android: Inflate exception on custom view 【发布时间】:2012-05-25 12:46:41 【问题描述】:

我有一个自定义视图,它使用这些构造函数扩展了 LinearLayout:

public class CustomView extends LinearLayout 

public CustomView(Context context) 
    this(context, null);


public CustomView(Context context, AttributeSet attrs) 
    this(context, attrs, R.attr.customViewStyle);


public CustomView(Context context, AttributeSet attrs, int defStyle) 
    super(context, attrs, defStyle);
    /* set custom attributes with TypedArray */


    /* other methods */

在我的 /res/values/attrs.xml 中:

<attr name="customViewStyle" format="reference" />

<declare-styleable name="CustomeView">
    <attr name="value" format="integer" />
    <attr name="android:imeOptions" />
    <attr name="android:imeActionId" />
    <attr name="android:imeActionLabel" />
</declare-styleable>

在我的 /res/values/styles.xml 中:

<style name="AppTheme" parent="@android:style/Theme.Black">
    <item name="android:windowBackground">@drawable/bg_dark_fiber</item>
    <item name="customViewStyle">@style/CustomViewStyle</item>
</style>

<style name="CustomViewStyle">
    <item name="android:clickable">true</item>
    <item name="android:focusable">true</item>
    <item name="android:focusableInTouchMode">true</item>
</style>

AppTheme 被设置为整个应用程序的主题。期望的结果是我的自定义视图默认是可聚焦和可点击的,而无需在我的布局文件中添加这些属性(而常规的 LinearLayout 不是)。当我运行该应用程序时,它会崩溃并显示以下堆栈跟踪:

05-17 14:58:53.010: E/ActivityThread(26767): Failed to inflate
05-17 14:58:53.010: E/ActivityThread(26767): android.view.InflateException: Binary XML file line #8: Error inflating class com.example.customviews.CustomView
05-17 14:58:53.010: E/ActivityThread(26767):    at android.view.LayoutInflater.createView(LayoutInflater.java:518)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:570)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
05-17 14:58:53.010: E/ActivityThread(26767):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:212)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.app.Activity.setContentView(Activity.java:1657)
05-17 14:58:53.010: E/ActivityThread(26767):    at com.example.pincode.PinCodeActivity.onCreate(PinCodeActivity.java:26)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.app.ActivityThread.access$1500(ActivityThread.java:123)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.os.Looper.loop(Looper.java:130)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.app.ActivityThread.main(ActivityThread.java:3835)
05-17 14:58:53.010: E/ActivityThread(26767):    at java.lang.reflect.Method.invokeNative(Native Method)
05-17 14:58:53.010: E/ActivityThread(26767):    at java.lang.reflect.Method.invoke(Method.java:507)
05-17 14:58:53.010: E/ActivityThread(26767):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
05-17 14:58:53.010: E/ActivityThread(26767):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
05-17 14:58:53.010: E/ActivityThread(26767):    at dalvik.system.NativeStart.main(Native Method)
05-17 14:58:53.010: E/ActivityThread(26767): Caused by: java.lang.reflect.InvocationTargetException
05-17 14:58:53.010: E/ActivityThread(26767):    at java.lang.reflect.Constructor.constructNative(Native Method)
05-17 14:58:53.010: E/ActivityThread(26767):    at java.lang.reflect.Constructor.newInstance(Constructor.java:415)
05-17 14:58:53.010: E/ActivityThread(26767):    at android.view.LayoutInflater.createView(LayoutInflater.java:505)
05-17 14:58:53.010: E/ActivityThread(26767):    ... 21 more
05-17 14:58:53.010: E/ActivityThread(26767): Caused by: java.lang.NoSuchMethodError: android.widget.LinearLayout.<init>
05-17 14:58:53.010: E/ActivityThread(26767):    at com.example.customviews.CustomView.<init>(CustomView.java:98)
05-17 14:58:53.010: E/ActivityThread(26767):    at com.example.customviews.CustomView.<init>(CustomView.java:94)
05-17 14:58:53.010: E/ActivityThread(26767):    ... 24 more

我不明白是什么导致了对 super(context, attrs, defStyle) 的调用中的 InflateException。我也尝试了super(context, attrs, 0),但这并没有帮助,这真的很奇怪,因为即使是 LinearLayout 也使用它,就像我检查过源代码的大多数其他视图一样。

【问题讨论】:

How to run a custom view with three-argument version constructor on pre-Honeycomb devices?的可能重复 【参考方案1】:

我在 Android Developers Google Group 上找到了这个答案:

LinearLayout构造函数的三参数版本只有 适用于 API 11 及更高版本 - 即 Android 3.0。

实际的 Android 必须在运行时满足此依赖关系 在设备上运行的版本。

我正在运行 Gingerbread (2.3.3) 的手机上进行测试。果然,当我在带有 ICS (4.0.3) 的模拟器上运行程序时,它运行良好。仍在寻找解决方法,以便我可以在蜂窝之前的代码中使用我的代码。

【讨论】:

【参考方案2】:

您的构造函数正在调用this 而不是super。如果你改变它,那么它会起作用。

我刚刚用构造函数扩展了线性布局来测试它是否有效。

【讨论】:

一个构造函数通过“this”调用另一个构造函数没有任何问题——如果有,代码将无法编译。错误发生在“super”调用上。【参考方案3】:

我在自定义 LinearLayout 时也遇到了这个问题。我所做的是在构造函数中调用super 而不是this,并在单独的方法中设置属性。

public class CustomView extends LinearLayout 

public CustomView(Context context) 
    super(context);


public CustomView(Context context, AttributeSet attrs) 
    super(context, attrs);


public CustomView(Context context, AttributeSet attrs, int defStyle) 
    super(context, attrs, defStyle);
    setAttributes(attrs);


private void setAttributes(AttributeSet attrs) 
    /* set custom attributes with TypedArray */

    /* other methods */

【讨论】:

以上是关于Android:自定义视图上的膨胀异常的主要内容,如果未能解决你的问题,请参考以下文章

具有自定义样式的TextView导致奇怪的膨胀异常

具有自定义样式的 TextView 导致奇怪的膨胀异常

在 Android 中膨胀视图后,自定义视图子项为空

Android:在片段内膨胀自定义视图

如何使用Android自定义视图中的属性设置调整膨胀布局的大小?

如何处理 Android 中远程视图的异常(自定义小部件或自定义通知)?