【问题标题】:Android Studio layout editor cannot render custom viewsAndroid Studio 布局编辑器无法呈现自定义视图
【发布时间】:2013-05-11 16:08:49
【问题描述】:

在 Android Studio 中,布局编辑器无法预览 xml 中的自定义视图。

非常简单的例子:

public class MyCustomView extends FrameLayout {
    public MyCustomView(Context context) {
        super(context);
    }

    public MyCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
}

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <com.myprojectxxx.view.MyCustomView
        android:layout_width="48dp"
        android:layout_height="48dp" />

</LinearLayout>

Android Studio 总是说,

渲染问题

找不到以下类:

  • com.myprojectxxx.view.MyCustomView(修复构建路径,创建类)

提示:尝试构建项目

当然,我有这门课。如果我单击“创建类”,它会抱怨同一个类已经存在。如果我重建那个项目,什么都不会改变。

而且,是的,该项目在我的 Android 设备上运行良好。此外,它在 Eclipse ADT 中呈现得非常好。但是,在 Android Studio 中,它总是说“无法找到类”。

Android Studio 无法使用自定义视图预览 xml 文件?这有什么问题?

【问题讨论】:

  • SO 不是为处于 Alpha 阶段的软件获得技术支持的地方。转到 Google 设置的任何地方讨论问题并在那里解释您的错误。
  • 但是blogs.jetbrains.com/idea/2011/10/… IntelliJ IDEA 已经有了这个功能。 “还支持并正确显示自定义视图组件。” Android Studio Preview 不支持这个功能?

标签: java android android-layout android-custom-view android-studio


【解决方案1】:

应该通过以下提交来修复。

https://android-review.googlesource.com/#/c/59090/

【讨论】:

  • 2.2.3 - 仍未修复:(
【解决方案2】:

我今天终于发现,布局渲染过程中的“Classdef not found”等错误实际上是误导性的。他们真正的意思是在您的小部件执行期间存在一些错误。

找出问题所在的最简单方法是:

  1. 在您的 XML 布局文件中,将您的自定义视图类(为清楚起见我们称之为“MyFrameLayout”)替换为 Android 库存类(例如 FrameLayout),并确保布局编辑器正常工作。 添加“工具:...”属性以允许您查看内容,而不是空布局。例如。如果您的自定义视图中有 EditText 小部件,请向其中添加此属性,该属性仅在设计模式下使用:

    tools:text="Sample content"
    

("tools: 命名空间是Android Studio自动添加的)

  1. 将您的原始类名(例如“MyFrameLayout”)返回到 XML 布局。现在可以用了吗?

如果没有:

  1. 为方便起见,将自定义视图的定义复制到一个临时的新类(例如“MyFrameLayoutBeforeFix”)。您将使用它与“MyFrameLayout”类进行比较,现在您将开始修改。

  2. 使用 Android Studio 从头开始​​重新创建“MyFrameLayout”类,从绝对最小值开始:它应该可以编译。因此,Java 类将包含“扩展“FrameLayout”和所需的构造函数/方法,例如在这种情况下:

    package com.myprojectxxx.view;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.FrameLayout;
    
    public class MyFrameLayout  extends FrameLayout {
        public MyFrameLayout(Context context) {
            super(context);
        }
    
        public MyFrameLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    }
    
  3. 确保此自定义视图正常呈现。至少应该在 2016 年!

  4. 将代码从“MyFrameLayoutBeforeFix”副本中逐段移动到此类,检查每一步都没有错误...

上面的顺序似乎很明显,但它对我有用。诀窍是布局编辑器在自己的上下文中启动您的类,这可能会导致代码中出现一些意外错误,当从应用程序内部启动时,这些错误“有效”...

另一个技巧是使用isInEditMode() 签入小部件的代码来跳过部分,这在设计视图中可能不起作用。例如:

MyClass myClass = isInEditMode() ? null : MyClass.getInstance();

【讨论】:

  • 连第 1 步都不懂。添加“tools:...”是什么意思?您在哪里添加此声明?你的意思是` xmlns:tools="schemas.android.com/tools" `还是其他一些工具命令?在第 3 步中,您说的是哪个“新类”——有问题的自定义类还是一些毫无意义的全新类?对不起,但我很困惑。看来您找到了解决方案,但我没有遵循您的逻辑。
【解决方案3】:

面对同样的问题,我不得不重写三个和四个参数的构造函数:

public View(Context context, AttributeSet attrs, int defStyle) public View(Context context, AttributeSet attrs, int defStyle, int defStyleRes)

然后重建项目。

【讨论】:

  • 这似乎对我有帮助。我说“似乎”是因为我过去已经设法“修复”了这个错误,然后它又在我身上跳出来了。但到目前为止好的!区别(到目前为止)似乎是需要使用 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 覆盖这个 4 参数构造函数,因为我的目标低于棒棒糖......
【解决方案4】:

IDEA 也支持并正确显示自定义视图组件,但由于 IntelliJ IDEA 使用输出目录中的类文件来呈现此类组件,因此您必须先在项目上执行 build->make project。

reference

【讨论】:

    【解决方案5】:

    这也可能是因为您使用了错误的主题来呈现您的布局。确保选择您在项目中使用的那个。

    【讨论】:

      【解决方案6】:

      不需要奇怪的构造函数参数!这完全是误会! 使用常规 2-arg (context + xmlattrs) 构造函数的 Android Studio 4.1 及更高版本的工作案例:

      1. 导航到您的 CustomView.kt 课程
      2. 打开“拆分”视图
      3. 点击这个问题图标
      4. 阅读错误信息,观察布局预览代码在哪里崩溃
      5. 修复这些错误!在我的情况下,布局预览无法获取字体,因此我观察到构造函数代码失败了。我已通过使用isInEditMode 标志设置布局预览识别的默认字体来解决此问题:
          private val defaultTypeface: Typeface = if (!isInEditMode) {
              ResourcesCompat.getFont(context, R.font.sfpro_bold)!!
          } else {
              Typeface.DEFAULT
          }
      
      

      【讨论】:

        猜你喜欢
        • 2016-10-11
        • 2020-08-15
        • 2015-09-13
        • 2018-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多