在本教程中,将学习如何使用Xamarin创建一个自定义的ListView适配器。与ASP.NET的ListView/GridView不同,Android中的ListView需要为每个列表项提供一个视图,并且需要为该视图中的控件提供值。在学习过程中,可能会感觉像是在MFC中继承CButton类。
首先,通过选择“文件”->“新建”->“项目”来创建一个新的Android应用程序,并命名为“CustomListBox”。
项目创建完成后,打开“资源”文件夹下的“布局”,并添加一个名为custListItem.axml的新文件。
在布局文件中,添加以下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"
android:minWidth="25px"
android:minHeight="25px">
<LinearLayout
android:orientation="horizontal"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/linearLayout1">
<ImageView
android:src="@android:drawable/ic_menu_gallery"
android:layout_width="46.7dp"
android:layout_height="wrap_content"
android:id="@+id/IMG1"
android:layout_marginRight="9.3dp"/>
<TextView
android:text="Text"
android:layout_width="159.3dp"
android:layout_height="fill_parent"
android:id="@+id/textName"
android:layout_marginRight="30.6dp"
android:gravity="center_vertical"
android:paddingRight="10dp"
android:paddingLeft="10dp"/>
<TextView
android:text="Text"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/textAge"
android:gravity="center_vertical"
android:paddingLeft="10dp"/>
</LinearLayout>
</LinearLayout>
在这个布局文件中,创建了一个LinearLayout,其中包含一个ImageView和两个TextView。接下来,将创建一个名为customListAdapter的类,并继承自BaseAdapter
定义一个PersInfo类,它将作为ListView的列表项。
public class PersInfo
{
public string Name { get; set; }
public string Age { get; set; }
public int ImageID { get; set; }
}
每个PersInfo对象将作为ListView的列表项。
接下来,实现BaseAdapter
public class customListAdapter : BaseAdapter
{
#region implemented abstract members of BaseAdapter
public override long GetItemId(int position)
{
throw new NotImplementedException();
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
throw new NotImplementedException();
}
public override int Count
{
get
{
throw new NotImplementedException();
}
}
#endregion
#region implemented abstract members of BaseAdapter
public override PersInfo this[int position]
{
get
{
throw new NotImplementedException();
}
}
#endregion
}
然后,添加两个私有成员,一个是List
GetView方法是ListView适配器中最典型的部分。需要根据位置获取项,然后检查convertView是否有内存。如果没有,使用保存的Activity对象创建custListItem布局的视图。
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = this._perInfoList[position];
var view = convertView;
if (convertView == null || !(convertView is LinearLayout))
view = _Context.LayoutInflater.Inflate(Resource.Layout.custListItem, parent, false);
var textName = view.FindViewById(Resource.Id.textName) as TextView;
var textAge = view.FindViewById(Resource.Id.textAge) as TextView;
var textPlace = view.FindViewById(Resource.Id.IMG1) as ImageView;
textName.SetText(item.Name, TextView.BufferType.Normal);
textAge.SetText(item.Age, TextView.BufferType.Normal);
textPlace.SetImageResource(item.ImageID);
return view;
}
在这里,根据位置获取项,然后检查convertView是否有内存。如果没有,使用保存的Activity对象创建custListItem布局的视图。然后,使用FindViewById方法找到TextView和ImageView,并根据传入的位置从PersInfo项中分配值。
现在,已经准备好了适配器和ListItem视图,接下来将在主活动中使用这些代码。在Main.axml中添加一个ListView控件,然后代码将如下所示:
<?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"
android:minWidth="25px"
android:minHeight="25px">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/listView1"/>
</LinearLayout>
在Resources -> Drawable文件夹中添加一些图片,例如羽毛球拍、足球和雪人。
接下来,初始化_perInfoList类型的私有变量,并为其提供一些初始值:
_perInfoList = new System.Collections.Generic.List<PersInfo>()
{
new PersInfo(){ Name="Alok Gupta", Age="31", ImageID=Resource.Drawable.SnowMan},
new PersInfo(){ Name="Jasdeep Singh", Age="31", ImageID=Resource.Drawable.FootBall},
new PersInfo(){ Name="Ritesh Thakur", Age="34", ImageID=Resource.Drawable.Badmitton}
};
在这里,这个列表将作为CustomAdapter的数据源。然后,使用FindViewById<ListView>方法找到ListView,并使用当前活动和在上一步中创建的列表集合创建customListAdapter,然后将其分配给ListView对象的Adapter属性。
var listViewObj = FindViewById<ListView>(Resource.Id.listView1);
listViewObj.Adapter = new customListAdapter(this, _perInfoList);
ListView将内部调用customListAdapter的GetView和Count方法来构建ListView。
最后,添加ListView.ItemClick事件处理器,并在处理器代码中添加Toast以生成点击用户的名称消息。
listViewObj.ItemClick += new EventHandler<AdapterView.ItemClickEventArgs>(OnListItemClick);
void OnListItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
Toast.MakeText(this, "You Click on name " + _perInfoList[e.Position].Name, ToastLength.Long).Show();
}