MonoAndroid:用 C# 编写自定义通用 BaseAdapter
使用通用 BaseAdapter 生成 ListView。
引言
在过去几周里,我一直在从事 Mono-Android 项目,在本篇文章中,我将创建一个自定义的通用 BaseAdapter 派生类来生成列表视图!
现在开始,创建 ListView 不像 ASP.net 的 ListView/GridView 那样直接,在 ASP.net 中,我们可以将列表集合直接附加到 ListView 并看到结果。而在 Android 世界中,情况有些不同,列表视图中的每个项目都代表一个视图,您必须为该视图中的控件提供值。在我学习的过程中,我感觉就像在 MFC 中继承 CButton 类一样 
视频链接

我们将一步一步进行。
- 通过选择 New -> Solutions 来创建 Android 应用程序,并为其命名为 “CustomListBox”
  图 1:创建Android项目! 图 1:创建Android项目!
- 项目创建完成后,打开 Resource Folder -> Layout 并添加一个名为 custListItem.axml 的新文件
  图 2:选择新文件! 图 2:选择新文件! 图 3 图 3
- 在布局文件中添加以下代码:<?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>我来解释一下我是如何创建这个布局文件的(您可以将其理解为 UI 前端)- 现在添加一个 LinearLayout,并设置orientation为 “Horizontal”
- 在这个 Horizontal Linear Layout 中添加 ImageView和两个TextView
- 其余部分我做了一些微调来格式化 ImageView和TextView
 
- 现在添加一个 
- 现在添加一个名为 customListAdapter的类,并继承自抽象泛型类BaseAdpater<PersInfo>,这是PersInfo类的代码。(类似于 Step2,而不是添加布局文件,添加 C# 类文件)public class PersInfo { public string Name {get;set;} public string Age {get;set;} public int ImageID {get;set;} }上述类的每个对象都将充当ListView的ListItem。
- 现在,实现 BaseAdapter<PersInfo>,其基本骨架类看起来如下:public class customListAdapter1: BaseAdapter<PersInfo> { #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<PersInfo>和Activity的私有成员
- 添加一个 带参数的构造函数,它接受 Activity和List<PersInfo>作为参数,并将这些值分配给第一步中列出的私有成员。 
- 编码 GetItemIdCount和this [int position]非常简单,在 GetItemId 中:我们只是将位置作为 itemID 返回;在 Count 中:我们返回列表的计数;在 this [int position] 中:我们将返回指定位置的项。
- 现在我们来到最典型的部分,编写 GetView 函数
 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布局类型的视图。现在,由于我们已经提供了 custListItem视图,使用FindViewById方法找到TextView和ImageView,并根据传入的位置从PersInfo项中为其赋值。
- 现在添加两个类型为 
- 现在您的 adapter 和 ListItem 视图已准备就绪,现在我们将编写主 Activity 来使用上述代码。在 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 文件夹中添加一些图片,就像我添加的羽毛球拍、足球和雪人图片一样。 
    雪人 足球 羽毛球 
- 现在添加一个类型为 List<PersInfo> 的私有变量 _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的馈送器。
 
- 现在,您可以使用 id “Resource.Id.listView1” 通过 FindViewById<ListView> 找到 ListView ,并通过传递当前 Activity 和我们在上一步创建的列表集合来创建我们的 customListAdapter ,并将其分配给 ListView 对象的 adapter 属性。var listViewObj = FindViewById<ListView> (Resource.Id.listView1); listViewObj.Adapter = new customListAdapter (this, _perInfoList); ListView 将内部调用 customListAdapter 的 GetView 和 Count 方法来构建列表视图。
- 现在添加 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 (); }您可以在 此处 阅读更多关于Toast类的信息。
- 现在构建并运行!(这是 3.4 英寸模拟器图像)
   
关注点
我使用了MonoAndroid (C#)和Xamarin Studio来构建本教程。请留意,如果我继续学习,您可能会期待更多文章即将发布。
虽然 Xamarin Studio 是专有软件,但他们提供了免费的入门版来构建、测试和发布 Android 应用程序。我正在使用它来学习。
本系列文章!
- MonoAndroid:在您的移动应用程序中使用 GridView
- MonoAndroid:在移动应用程序中使用 TabHost
- MonoAndroid:在移动应用中使用 Fragments
- MonoAndroid:使用 dotnet Web 服务(ASMX)
- MonoAndroid:使用 Started Service
- MonoAndroid:调用次级活动
- MonoAndroid:用 C# 编写 ExpandableListView 和 BaseExpandableListAdapter
- MonoAndroid:使用 AlertDialog
本系列技巧/窍门
- MonoAndroid:Android 通知服务
- MonoAndroid:使用绑定服务
- MonoAndroid:用 C# 编写 ExpandableListView 和 BaseExpandableListAdapter
历史
- 2013 年 7 月 30 日:第一个版本
- 2013 年 8 月 1 日:最初遗漏了什么,现在已包含。
- 2013 年 8 月 22 日:更新了本系列文章列表
- 2013 年 9 月 6 日:更新了技巧与窍门部分。
- 2013 年 10 月 11 日:更新了文章部分。
- 2013 年 11 月 5 日:添加了视频链接
- 2013年11月22日:更新了其他文章部分




