Пользовательский вид в формате XML - PullRequest
14 голосов
/ 16 июля 2010

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

17 голосов
/ 16 июля 2010

Вы хотите:

<?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);
}

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

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

11 голосов
/ 05 октября 2011

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

...