【问题标题】:Error referencing an inner class View in layout/main.xml在 layout/main.xml 中引用内部类视图时出错
【发布时间】:2011-01-07 02:03:50
【问题描述】:

咕噜……

我在我的 Activity 中创建了一个视图子类作为内部类。在我从我的活动中简单地链接到此视图之前:

setContentView(new CustomView(this));

没有问题。

但是,现在,我的视图变得越来越复杂,因此我将其作为 FrameLayout 的一部分,以便我可以将其作为基本视图并在其顶部添加一个 Spinner 小部件。问题是,当我这样做时出现错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.grafightscratch.ochemmer/com.grafightscratch.ochemmer.MoleculeTablet}: android.view.InflateException: Binary XML file line #4: Error inflating class com.grafightscratch.ochemmer.MoleculeTablet.MoleculeTabletView
...
Caused by: android.view.InflateException: Binary XML file line #4: Error inflating class com.grafightscratch.ochemmer.MoleculeTablet.MoleculeTabletView
...
Caused by: java.lang.ClassNotFoundException: com.grafightscratch.ochemmer.MoleculeTablet.MoleculeTabletView in loader dalvik.system.PathClassLoader@43b74a28

所以,当我直接链接到它之前,这个视图有效,但是当我尝试将它作为框架布局的一部分添加到 main.xml 文件中时,我得到了上述错误。我还尝试放入一个布局,仅通过以下方式显示它:

<com.grafightscratch.ochemmer.MoleculeTablet.MoleculeTabletView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/molecule_tablet_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

没有任何作用。我不断收到 InflateException/ClassNotFoundException 错误。它抱怨二进制 XML 文件中的“第 3 行”,如果它在谈论 main.xml,那就是我已经三重检查的包声明。

编辑 我尝试使这个视图成为一个单独的类(即不是内部类)并且它有效。经过一番搜索,我发现一些帖子说 xml 标签应该是这样的:

<com.grafightscratch.ochemmer.MoleculeTablet$MoleculeTabletView ...>

即,应使用美元符号将内部类与主类分开。但是,Eclipse 对此表示反对,称其为错误,并拒绝让我在那里使用该角色构建或部署。所以现在的问题变成了:如何引用作为内部类的 View?

【问题讨论】:

    标签: android layout view


    【解决方案1】:

    我遇到了同样的问题。但是,XML 文件中的语法是正确的。

    最终为我解决的问题是内部类需要声明为静态。例如:

    public static class myWebView extends WebView
    

    【讨论】:

    • 这里也一样。缺少静态关键字也是我的问题。
    【解决方案2】:

    以下是在内部类中创建自定义视图的一些关键点...

    public static class MainClass {
        ....
        ....
            public class SubClassView extends LinearLayout {
               public SubClassView(Context context, AttributeSet attrs) {
                    super(context, attrs);
                    .....
               }
        ....
        ....
           }
        }
    

    布局应该如下:

    <view class = ".MainClass$SubClassView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/button"/>
    

    Java 类

    • 静态是必需的
    • constructor 必须带有 AttributeSet(至少一个)

    XML 文件

    • view 标记(小写 NOT View)是必需的
    • class 标签 与你的内部类的路径,使用
    • $ 而不是“。”在您的 SubClassView 名称之前

    【讨论】:

      【解决方案3】:

      对于内部类:

      <view class="{package}.{ParentClass}${innerClass}" />
      

      对于内部类,你必须声明你的类:

      public static InnerClass
      

      static 是必需的。

      【讨论】:

        【解决方案4】:
        <view xmlns:android="http://schemas.android.com/apk/res/android"
            class="com.example.Myproject.Myactivity$Myview"
             android:layout_width="fill_parent" android:id="@+id/name" android:visibility="visible" android:layout_gravity="bottom" android:layout_height="fill_parent" android:focusableInTouchMode="true"
        />
        

        这段代码对我有用。当我遗漏了一些像 layout_width 这样的元素时,我的程序崩溃了。我还必须将视图类设为静态才能使其正常工作。最后,如果我只是把它从它的巢穴里拿出来,它会是一样的。 android note 示例使用嵌套类。

        【讨论】:

          【解决方案5】:

          对于内部类,语法变为:

          <view class="com.grafightscratch.ochemmer.MoleculeTablet$MoleculeTabletView" />
          

          原因是 $ 是 XML 标签中的非法字符。

          【讨论】:

          • 请注意,xml 标签可能需要比View 标签更接近您的班级(在我的情况下,我需要ViewGroup
          • 虽然我没有收到错误,但当我获取视图(使用 findViewById)时,我得到了 android.view.View 的实例,而不是内部类的实例。什么给了?
          • 确保 xml 视图标签为小写,然后您应该能够将其转换为您指定的类
          • 不幸的是,如果您想将您的课程包含在PreferenceScreen XML 布局中,则此答案不起作用。你得到java.lang.ClassNotFoundException: Didn't find class "android.preference.view"。我发现解决这个问题的唯一方法是将静态嵌套类提升为自己文件中的成熟类,这并不理想。另见stackoverflow.com/q/7249028/1843329
          【解决方案6】:

          您需要在 XML 中指定视图类的完全限定名称,以使膨胀工作和运行时系统找到视图类。
          由于您已将 View 声明为活动的内部类,因此完全限定名称将是:&lt;your_package_name&gt;.OuterClassName.InnerClassName

          您确定 com.grafightscratch.ochemmer.CustomView 是您班级的完全限定名吗?

          编辑:感谢您提醒我这一点。当视图被声明为嵌套类时,会有轻微的偏差,请参阅本文档的Use Custom component

          【讨论】:

          • Ahhhh...你抓住了我——为了清楚起见,我试图编辑这篇文章,结果却引入了一个“发布错误”。好的 - 我只是要剪切和粘贴,以便它反映实际的代码。
          • 好的——问题现在反映了真正的包名。但是是的 - 这仍然是一个问题。
          • 查看本页中的“使用自定义组件部分”:developer.android.com/intl/fr/guide/topics/ui/…
          • 感谢 Samuh,该文档有帮助。这似乎表明使内部类静态也是必要的。虽然这似乎解决了我的问题,但这意味着它引用的外部类中的所有字段也需要是静态的。没有静态类有没有办法做到这一点?
          • IMO,是否将类设为静态是您做出的设计选择。如果这个类可以独立存在,那么它本身就是静态的。如果它需要与外部类的实例绑定,它应该是非静态的。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多