65.9K
CodeProject 正在变化。 阅读更多。
Home

MonoAndroid:用 C# 编写自定义通用 BaseAdapter

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.65/5 (10投票s)

2013年7月30日

CPOL

4分钟阅读

viewsIcon

61065

downloadIcon

636

使用通用 BaseAdapter 生成 ListView。

引言

在过去几周里,我一直在从事 Mono-Android 项目,在本篇文章中,我将创建一个自定义的通用 BaseAdapter 派生类来生成列表视图!

现在开始,创建 ListView 不像 ASP.net 的 ListView/GridView 那样直接,在 ASP.net 中,我们可以将列表集合直接附加到 ListView 并看到结果。而在 Android 世界中,情况有些不同,列表视图中的每个项目都代表一个视图,您必须为该视图中的控件提供值。在我学习的过程中,我感觉就像在 MFC 中继承 CButton 类一样

视频链接



我们将一步一步进行。

  1. 通过选择 New -> Solutions 来创建 Android 应用程序,并为其命名为 “CustomListBox

    图 1:创建Android项目!

  2.  
  3. 项目创建完成后,打开 Resource Folder -> Layout 并添加一个名为 custListItem.axml 的新文件

    图 2:选择新文件! 

    图 3

  4. 在布局文件中添加以下代码:
    <?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
  5. 现在添加一个名为 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

  6. 现在,实现 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>作为参数,并将这些值分配给第一步中列出的私有成员。
    • 编码 GetItemId, Count 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 项中为其赋值。

  7. 现在您的 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> 
    

  8. Resources -> Drawable 文件夹中添加一些图片,就像我添加的羽毛球拍、足球和雪人图片一样。 
    雪人 足球 羽毛球

  9. 现在添加一个类型为 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 的馈送器。

  10. 现在,您可以使用 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 方法来构建列表视图。

  11. 现在添加 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 类的信息。

  12. 现在构建并运行!(这是 3.4 英寸模拟器图像)

关注点

我使用了MonoAndroid (C#)Xamarin Studio来构建本教程。请留意,如果我继续学习,您可能会期待更多文章即将发布。

虽然 Xamarin Studio 是专有软件,但他们提供了免费的入门版来构建、测试和发布 Android 应用程序。我正在使用它来学习。 

本系列文章!

本系列技巧/窍门

历史  

  • 2013 年 7 月 30 日:第一个版本
  • 2013 年 8 月 1 日:最初遗漏了什么,现在已包含。 
  • 2013 年 8 月 22 日:更新了本系列文章列表
  • 2013 年 9 月 6 日:更新了技巧与窍门部分。 
  • 2013 年 10 月 11 日:更新了文章部分。 
  • 2013 年 11 月 5 日:添加了视频链接
  • 2013年11月22日:更新了其他文章部分
© . All rights reserved.