XML布局中的自定义视图

14

我创建了一个继承自SurfaceView类的视图。

但是我不知道如何将它从xml布局文件中添加进来。我的当前main.xml看起来像这样:

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

<View
    class="com.chainparticles.ChainView"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" 
    />


</LinearLayout>

我错过了什么?

编辑

更多信息

我的视图长这样

package com.chainparticles;
public class ChainView extends SurfaceView implements SurfaceHolder.Callback {
    public ChainView(Context context) {
        super(context);
        getHolder().addCallback(this);
    }
// Other stuff
}

这样做很好:

ChainView cview = new ChainView(this);
setContentView(cview);

但是,在xml中尝试使用它时没有任何反应。

2个回答

18
你想要:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>

    <com.chainparticles.ChainView
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" 
     />
</LinearLayout>

编辑:

看完你的代码后,很可能是因为你在构造函数中被填充时无法调用getHolder而导致错误。将其移到View#onFinishInflate中。

所以:

@Override
protected void onFinishInflate() {
    getHolder().addCallback(this);
}
如果那个方法不起作用,尝试将其放在一个init函数中,在你的ActivitysetContentView之后调用它。
之前它可能是工作的,因为当从xml填充时,会调用构造函数:View(Context, AttributeSet)而不是View(Context)

通过我的第一个布局,我只得到了一个黑屏,这样应用程序就会崩溃。 - monoceres
也许这些额外的建议会有所帮助。 - Rich Schuler
我明白了!关键是xml使用Context和AttributeSet调用了构造函数(正如你所说),因此添加该构造函数解决了问题。 非常感谢! - monoceres

11

在你的示例中,你遗漏了标签名称,应该是 "view"(第一个非大写字母),而不是 "View"。虽然大多数时候你可以将类名作为标签名,但如果你的类是内部类,则无法这样做,因为 "$" 符号用于引用 Java 中的内部类,而在 XML 标记中是受限的。 因此,如果你想在 XML 中使用内部类,应该像这样编写:

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

    <view
      class="com.chainparticles.Foo$InnerClassChainView"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" 
     />
</LinearLayout>

问题在于模式中存在 "view" 和 "View" 标签。以大写字母开头的 "View" 标签将生成一个 View 类,而小写字母开头的 "view" 标签解析时会检查 class 属性。


1
@SamusArin 给他点赞,哈哈,爱他。 - Sibbs Gambling
记得添加所有的构造函数。如果你正在重写View类,那么有3个构造函数:View(Context context),View(Context context, AttributeSet attrs)和View(Context context, AttributeSet attrs, int defStyleAttr)。 - SoloPilot
很棒的回答。+1 针对 View 和 view 标签的区别。 - Sankar V

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接