Пользовательский вид в макете xml

Я создал свой собственный вид, создав подкласс класса 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 ничего не происходит.

Ответ 1

Вы хотите:

<?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>

Edit:

После просмотра остальной части вашего кода он, вероятно, бросает, потому что вы не можете вызвать getHolder в конструкторе при раздувании. Переместите его на View#onFinishInflate

Итак:

@Override
protected void onFinishInflate() {
    getHolder().addCallback(this);
}

Если это не работает, попробуйте поместить это в функцию init, которую вы вызываете в Activity onCreate после setContentView.

Вероятно, он работал раньше, потому что при раздувании из xml конструктора: View(Context, AttributeSet) вызывается вместо View(Context).

Ответ 2

То, что вы пропустили в своем примере, было именем тега, оно должно быть "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" при анализе проанализирует атрибут класса.