Как создать простой пользовательский вид?

Я хочу создать собственный View на Android. Я попытался сделать это как можно проще и создал почти пустой класс MyView и использовал его в своем LinearLayout, но приложение не работает при запуске с помощью «Force Close». Как я могу сделать простой пользовательский View? Согласно Создание пользовательских компонентов, View получает размер 100x100, если Я не отменяю onMeasure().

public class MyView extends View {

    public MyView(Context context) {
        super(context);
    }
}

И я использую его в LinearLayout с:

<view
    class="com.example.MyView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.0" />

Что я делаю неправильно?


Если я использую конструктор, который предлагает itemon, и соответствующий вызов суперкласса. Затем «Принудительное закрытие» исчезло, но мой LinearLayout не работает, компоненты после MyView не отображаются.

Вот мой main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    >
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.0"
    android:background="#f00"
    android:text="Hello"
/>
<view
    class="com.example.MyView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.0"
/>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.0"
    android:background="#00f"
    android:text="World"
/>
</LinearLayout>

person Jonas    schedule 14.12.2010    source источник


Ответы (2)


может быть, вы могли бы определить другой метод конструктора, например:

public MyView(Context context, AttributeSet attrs)

платформа Android попытается создать пользовательский интерфейс с вашим представлением из конструктора выше.

person itemon    schedule 14.12.2010
comment
Спасибо, это удаляет сообщение о принудительном закрытии, но мой LinearLayout не работает, компонент после не отображается. - person Jonas; 14.12.2010

В Руководстве разработчика Android есть раздел «Создание пользовательских компонентов». К сожалению, обсуждение XML-атрибутов охватывает только объявление элемента управления внутри файла макета, а не фактическую обработку значений внутри инициализации класса. Шаги следующие:

Объявить атрибуты в values\attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyCustomView">
        <attr name="android:text"/>
        <attr name="android:textColor"/>            
        <attr name="extraInformation" format="string" />
    </declare-styleable>
</resources>

Обратите внимание на использование неквалифицированного имени в теге declare-styleable. Нестандартные атрибуты Android, такие как extraInformation, должны иметь объявленный тип. Теги, объявленные в суперклассе, будут доступны в подклассах без необходимости повторного объявления.

Создание конструкторов

Поскольку есть два конструктора, которые используют AttributeSet для инициализации, удобно создать отдельный метод инициализации для вызова конструкторов.

private void init(AttributeSet attrs){  
    TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.MyCustomView);
    //Use a
    Log.i("test",a.getString(R.styleable.MyCustomView_android_text));
    Log.i("test",""+a.getColor(R.styleable.MyCustomView_android_textColor, Color.BLACK));
    Log.i("test",a.getString(R.styleable.MyCustomView_android_extraInformation));
    //Don't forget this
    a.recycle();
}

R.styleable.MyCustomView — это автоматически сгенерированный ресурс int[], где каждый элемент является идентификатором атрибута. Атрибуты генерируются для каждого свойства в XML путем добавления имени атрибута к имени элемента. Затем атрибуты можно получить из TypedArray с помощью различных функций получения. Если атрибут не определен в XML, возвращается null. За исключением, конечно, случая, когда тип возвращаемого значения является примитивным, и в этом случае возвращается второй аргумент.

Если вы не хотите извлекать все атрибуты, можно создать этот массив вручную. Идентификаторы стандартных атрибутов Android включены в android.R.attr, а атрибуты для этого проекта — в R.attr.

int attrsWanted[]=new int[]{android.R.attr.text, R.attr.textColor};

Обратите внимание, что вы не должны ничего использовать в android.R.styleable, так как в этой теме это может измениться в будущем. Это все еще находится в документации, так как просмотр всех этих констант в одном месте полезен.

Используйте его в файлах макета, таких как layout\main.xml. Включите объявление пространства имен.

xmlns:app="http://schemas.android.com/apk/res/com.mycompany.projectname"

в элементе xml верхнего уровня.

<com.mycompany.projectname.MyCustomView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/transparent"
    android:text="Test text"
    android:textColor="#FFFFFF"
app:extraInformation="My extra information";
/> 

Ссылайтесь на пользовательское представление, используя полное имя.

Пример Android LabelView

Если вам нужен полный пример, посмотрите образец представления метки Android.

LabelView.java

TypedArray a=context.obtainStyledAttributes(attrs, R.styleable.LabelView);
CharSequences=a.getString(R.styleable.LabelView_text);
attrs.xml

<declare-styleable name="LabelView">
    <attr name="text"format="string"/>
    <attr name="textColor"format="color"/>
    <attr name="textSize"format="dimension"/>
</declare-styleable>

custom_view_1.xml

<com.example.android.apis.view.LabelView
    android:background="@drawable/blue"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    app:text="Blue"app:textSize="20dp"/>

Это содержится в LinearLayout с атрибутом пространства имен:

xmlns:app="http://schemas.android.com/apk/res/com.example.android.apis"

person Jai Agarwal    schedule 11.01.2012