专栏首页张志敏的技术专栏Mono for Android 下的 ListActivity

Mono for Android 下的 ListActivity

Mono for Android 下的 ListActivity

介绍 Mono for Android 平台下 ListActivity 的使用, 以及如何进行自定义 ListActivity 的 Adapter。

使用 ListActivity 最简单的方式

ListActivity 是 android 开发中很常用的布局组件, 通常用于显示可以滚动的列表项。 以 ArrayAdapter<T> 为例, 最简单的使用方法如下:

1、 新建一个 Activity , 名称为 MyListActivity , 并修改其基类为 Android.App.ListActivity, 代码如下:

[Activity (Label = "MyListApp", MainLauncher = true)]
public class MyListActivity : ListActivity {

	protected override void OnCreate(Bundle bundle) {
		base.OnCreate(bundle);
	}
}

2、 添加一个字符串数组字段作为数据源, 代码如下:

// 最简单的方法, 用数组作为数据源
private readonly string[] _countries = new String[] {
	"Afghanistan","Albania","Algeria","American Samoa","Andorra",
	"Angola","Anguilla","Antarctica","Antigua and Barbuda","Argentina",
	"Armenia","Aruba","Australia","Austria","Azerbaijan",
	"Bahrain","Bangladesh","Barbados","Belarus","Belgium",
	"Belize","Benin","Bermuda","Bhutan","Bolivia",
	"Bosnia and Herzegovina","Botswana","Bouvet Island","Brazil",
	"British Indian Ocean Territory"
};

3、 在 OnCreate 方法中设置 ListView 的数据源, 代码如下:

protected override void OnCreate(Bundle bundle) {
	base.OnCreate(bundle);
	// 设置 ListAdapter 为 ArrayAdapter<string>
	this.ListAdapter = new ArrayAdapter<string>(this, Resource.Layout.MyListActivityItemLayout, this._countries);
	this.ListView.TextFilterEnabled = true;
	// 添加一个建大的事件处理函数, 以通知的形式显示选中项。
	this.ListView.ItemClick += (object sender, AdapterView.ItemClickEventArgs e) => {
		var toast = Toast.MakeText(this.Application, ((TextView)e.View).Text, ToastLength.Short);
		toast.Show();
	};

}

现在, 完整的 MyListActivity.cs 看起来应该是这样子的:

[Activity(Label = "ListDemo", MainLauncher = true)]
public class MyListActivity : ListActivity {

	private readonly string[] _countries = new String[] {
		"Afghanistan","Albania","Algeria","American Samoa","Andorra",
		"Angola","Anguilla","Antarctica","Antigua and Barbuda","Argentina",
		"Armenia","Aruba","Australia","Austria","Azerbaijan",
		"Bahrain","Bangladesh","Barbados","Belarus","Belgium",
		"Belize","Benin","Bermuda","Bhutan","Bolivia",
		"Bosnia and Herzegovina","Botswana","Bouvet Island","Brazil",
		"British Indian Ocean Territory"
	};

	protected override void OnCreate(Bundle bundle) {
		base.OnCreate(bundle);

		// Create your application here
		this.ListAdapter = new ArrayAdapter<string>(this, Resource.Layout.MyListActivityItemLayout, this._countries);
		this.ListView.TextFilterEnabled = true;

		this.ListView.ItemClick += (object sender, AdapterView.ItemClickEventArgs e) => {
			var toast = Toast.MakeText(this.Application, ((TextView)e.View).Text, ToastLength.Short);
			toast.Show();
		};
	}
}

如果现在运行程序, 看到的效果如下:

ListActivity的使用就是这么简单, 但是这往往不是我们所需要的, 接下来将会对上面的代码进行一些重构。

使用 String-Array 作为 ListActivity 数据源

把要显示的列表作为 Android 资源是个不错的注意, 减少对显示内容的硬编码, 必要时还可以方便的实现多语言显示, 在 Assets/values/strings.xml 文件中添加下面的内容:

<string-array name="CountryArray">
	<item>Afghanistan</item>
	<item>Albania</item>
	<item>Algeria</item>
	<item>American Samoa</item>
	<item>Andorra</item>
	<item>Angola</item>
	<item>Anguilla</item>
	<item>Antarctica</item>
	<item>Antigua and Barbuda</item>
	<item>Argentina</item>
	<item>Armenia</item>
	<item>Aruba</item>
	<item>Australia</item>
	<item>Austria</item>
	<item>Azerbaijan</item>
	<item>Bahrain</item>
	<item>Bangladesh</item>
	<item>Barbados</item>
	<item>Belarus</item>
	<item>Belgium</item>
	<item>Belize</item>
	<item>Benin</item>
	<item>Bermuda</item>
	<item>Bhutan</item>
	<item>Bolivia</item>
	<item>Bosnia and Herzegovina</item>
	<item>Botswana</item>
	<item>Bouvet Island</item>
	<item>Brazil</item>
	<item>British Indian Ocean Territory</item>
</string-array>

然后, 在 OnCreate 方法中这样初始化 ArrayAdapter :

var countries = Resources.GetStringArray(Resource.Array.CountryArray);
this.ListAdapter = new ArrayAdapter<string>(this,
 	Resource.Layout.MyListActivityItemLayout, countries);

现在的 MyListActivity 的源代码如下:

[Activity(Label = "ListDemo", MainLauncher = true)]
public class MyListActivity : ListActivity {

	protected override void OnCreate(Bundle bundle) {
		base.OnCreate(bundle);

		// 获取资源中定义的字符串数组
		var countries = Resources.GetStringArray(Resource.Array.CountryArray);
		this.ListAdapter = new ArrayAdapter<string>(this, Resource.Layout.MyListActivityItemLayout, countries);
		this.ListView.TextFilterEnabled = true;

		this.ListView.ItemClick += (object sender, AdapterView.ItemClickEventArgs e) => {
			var toast = Toast.MakeText(this.Application, ((TextView)e.View).Text, ToastLength.Short);
			toast.Show();
		};
	}
}

使用自定义 ListAdapter

在很多情况下, 还需要使用自定义的 ListAdapter , Mono for Android 版本的自定义 BaseAdapter 实现如下:

public class MyListAdapter : BaseAdapter<string> {

	private string[] _data;
	private Activity _activity;
	
	public MyListAdapter(Activity activity) {
		// 引用当前的 activity 是必须的, 否则貌似没办法调用 LayoutInflater
		this._activity = activity;
		// 从资源中加载数组数据
		this._data = activity.Resources.GetStringArray(Resource.Array.CountryArray);
	}

	// 重写 GetItemId 方法, 
	public override long GetItemId(int position) {
		return position;
	}

	// 重写 GetView 方法, 获取每个数据的单元格。
	public override View GetView(int position, View convertView, ViewGroup parent) {
		TextView view = convertView as TextView;
		if (view == null) {
			// 貌似只有通过 Activity 才能使用 LayoutInflactor , 
			view = (TextView)this._activity.LayoutInflater.Inflate(Resource.Layout.MyListActivityItem, null);
		}
		view.Text = this._data[position];
		return view;
	}

	// 重写 Count 属性, 只有 Mono for Android 才有
	public override int Count {
		get {
			return this._data.Length;
		}
	}

	// 实现 this 索引器, 这个也是 Mono for Android 才有的
	public override string this[int position] {
		get {
			return this._data[position];
		}
	}

}

从上面的代码可以看出, Mono for Android 提供的 BaseAdapter<T> 有着浓厚的 .Net 风格, 比如 Count 属性, this 索引器 等, 当然, 这些对于有经验的 .net 开发人员来说, 都是已经掌握的知识了。 使用这个自定义 Adapter 也是非常方便的, 只要用将 ListActivity 的初始化代码改成这样就行:

var arrayAdapter = new MyListAdapter(this);
this.ListAdapter = arrayAdapter;
this.ListView.TextFilterEnabled = true;

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS 应用使用位置信息

    当程序运行时, 用户直接锁定屏幕, 会调用 AppDelegate 的 DidEnterBackground 方法, 但是对于 iOS 应用来说, 用户切换程序...

    beginor
  • 使用 docker-compose 替代 docker run

    要运行一个 docker 镜像, 通常都是使用 docker run 命令, 在运行的镜像的时候, 需要指定一些参数, 例如:容器名称、 映射的卷、 绑定的端口...

    beginor
  • 在 ASP.NET WebAPI 中使用 DataAnnotations 验证数据

    为了 Web 服务的安全, 通常在服务端也会做数据验证, 不过数据验证的代码确实是有点儿枯燥, 以简单的用户注册来说, 需要的注册信息如下:

    beginor
  • Android中string-array用法

    String[] pros=this.getResources().getStringArray(R.array.province_item);

    wust小吴
  • 详解基于内容的推荐算法

    本文介绍的将会是推荐系统最古老的算法:基于内容的推荐算法(Content-Based Recommendations CB)。

    机器学习算法工程师
  • Android项目实战(八):列表右侧边栏拼音展示效果

    听着music睡
  • [探索]在开发中尽量提高代码的复用性

    相信很多人和我一样,在开发项目的时候,因为项目赶,或者一时没想到等原因。频繁使用 ctrl+c 和 ctrl+v ,导致代码很多都是重复的。这几天,也看了自己以...

    守候i
  • 史上最全国家统计局划分代码爬取

    由于工作中使用国家统计局划分的区域码,本文使用python爬取地方划分码,地址:http://www.stats.gov.cn/tjsj/tjbz/tjyqhd...

    LiosWong
  • 安卓-无敌解决ListView添加标题头无法正常显示的问题(歪门邪道)

    在做安卓实验时,用到了ListView来做表格显示数据。由于表头是使用xml布局文件动态实现的。造成了添加好组件后,无法正常显示的情况。浪费了我2小时的时间,终...

    TrueDei
  • python爬虫-爬取盗墓笔记

    七夜安全博客

扫码关注云+社区

领取腾讯云代金券