Расширение нулевой ссылки LinearLayout

Я хочу иметь возможность создать экземпляр нового пользовательского класса LinearLayout на основе макета, определенного в xml. Независимо от того, что я делаю, во время выполнения LinearLayout и все мои TextView выдают исключение нулевой ссылки.

TransferListRow.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp">
<TextView
    android:id="@+id/transferSerial"
    android:layout_width="0dp"
    android:layout_weight=".30"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:padding="5dp"
    android:gravity="center" />
<TextView
    android:id="@+id/transferModel"
    android:layout_width="0dp"
    android:layout_weight=".30"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:padding="5dp"
    android:gravity="center" />
<TextView
    android:id="@+id/transferSite"
    android:layout_width="0dp"
    android:layout_weight=".30"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:padding="5dp"
    android:gravity="center" />
<Button
    android:id="@+id/transferDelete"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:padding="5dp"
    android:gravity="center"
    android:src="@drawable/delete" />

TransferListRow.cs Attempt 1:

 sealed class TransferListRow : LinearLayout
 {
    private readonly Context _context;

    public TransferListRow(Context context, string serial, string model, string site)
        :base(context)
    {
        _context = context;

        LayoutInflator inflator = (LayoutInflator) _context.GetSystemService(Context.LayoutInflaterService);
        inflator.Inflate(Resource.Layout.transferListRow, null);

        TextView s = (TextView) FindViewById(Resource.Id.transferSerial);
        s.Text = serial;

        TextView m = (TextView) FindViewById(Resource.Id.transferModel);
        m.Text = model;

        TextView st = (TextView) FindViewById(Resource.Id.transferSite);
        st.Text = site;
    }
}

TransferListRow.cs Попытка 2:

sealed class TransferListRow : LinearLayout
{
    private readonly Context _context;

    public TransferListRow(Context context, string serial, string model, string site)
        :base(context)
    {
        _context = context;

        LinearLayout layout = (LinearLayout) FindViewById(Resource.Layout.transferListRow);

        TextView s = (TextView) layout.FindViewById(Resource.Id.transferSerial);
        s.Text = serial;

        TextView m = (TextView) layout.FindViewById(Resource.Id.transferModel);
        m.Text = model;

        TextView st = (TextView) layout.FindViewById(Resource.Id.transferSite);
        st.Text = site;

        AddView(s);
        AddView(m);
        AddView(st);
    }
}

Конечная цель заключалась бы в том, чтобы из моей основной деятельности можно было сделать что-то подобное в событии нажатия кнопки:

 mainLayout.AddView(new TransferListRow(this, "serial", "model", "site"));

person jmease    schedule 02.07.2012    source источник


Ответы (1)


1) Поскольку вы расширяете LinearLayout, ваш макет, определенный в XML, не должен иметь оболочку LinearLayout. Вместо этого используйте только <merge> ... </merge>.

2) В вашем конструкторе вы должны вызвать inflator.Inflate(Resource.Layout.transferListRow, this);. Обратите внимание на параметр this. Это раздует все элементы, определенные в вашем XML, в LinearLayout как дочерние элементы.

3) Фреймворк уведомит вас в onFinishInflate(), когда наполнение будет выполнено, и представления можно будет найти с помощью findViewById(). Итак, в onFinishInflate() вы можете назначать свои TextView своим переменным-членам.

Вот и все :)

person AZ13    schedule 02.07.2012
comment
Однако одно маленькое дополнение. По какой-то причине OnFinishInflate() никогда не происходит. Так что мне все равно пришлось присваивать значения моих TextViews в конструкторе, но теперь все работает. - person jmease; 02.07.2012
comment
хм, это действительно странно. Какой язык программирования вы используете? В ваших фрагментах кода это не Java, верно? - person AZ13; 03.07.2012
comment
Это С#. Я использую продукт под названием Mono для Android, который позволяет программировать приложения для Android в Visual Studio с помощью C#. - person jmease; 03.07.2012
comment
Является ли этот продукт открытым исходным кодом? У вас есть возможность заглянуть внутрь? Может быть, они по-разному относятся к такого рода событиям. - person AZ13; 03.07.2012