I want to be able to instantiate a new custom LinearLayout class based on a layout defined in xml. No matter what I do, at runtime, the LinearLayout and all of my TextViews throw a null reference exception.
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 Attempt 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);
}
}
End goal would be from my main activity be able to do something like this in a button click event:
mainLayout.AddView(new TransferListRow(this, "serial", "model", "site"));
1) Because you are extending LinearLayout, your layout definded in XML does not need to have a LinearLayout wrapper. Instead use just
<merge> ... </merge>.2) In your constructor you have to call
inflator.Inflate(Resource.Layout.transferListRow, this);. Please note the this parameter. This will inflate all elements defined in your XML into the LinearLayout as children.3) The framework will notify you in
onFinishInflate()when inflating is done and the views can be found withfindViewById(). So, inonFinishInflate()you can assign your TextViews to your member variables.That’s it 🙂