原文:Android(Xamarin)之旅(四)
这么晚了,可能也因为一点事情,就说打开博客园看看,结果 http://www.cnblogs.com/mindwind/p/5125248.html 这篇文章瞬间吸引了我。暗暗的回想一下,十年之后,我是什么样子,还是那样吗?为了生计奔波,为了那点渺茫的未来去争取……
在写这个的时候,我突然发现,我写的上一篇 三,竟然被转载了,哈哈,欢迎技术交流。
直接开始吧。
Android(Xamarin)之旅(一)
这片文章说到了Xamain的简单配置,Android文件的目录清单文件,还有一些简单的控件。
Android(Xamarin)之旅(二)
这篇文章对一些简单的控件做了介绍。还有界面的一部分清单。
Android(Xamarin)之旅(三)
这篇文章就说了一些简单的布局控件、提示信息设置和对话框设置。
今天我们主要说一下其他的数据组件、广播、服务。
一、数据组件
1、数据适配器
界面我们直接在左侧工具栏拖一个ListView过来,然后通过后台绑定数据。
var list = new List<IDictionary<string, object>>(); Random rand = new Random(); for (int i = 0; i < 8; i++) { var dic = new JavaDictionary<string, object>(); dic.Add("name", "Tel:" + i); dic.Add("time", " Re"+rand.Next(100,999)); list.Add(dic); } SimpleAdapter sam_adapter = new SimpleAdapter(this, list, Resource.Layout.layout_SimpleAdapter, new string[] { "name", "time" }, new int[] { Resource.Id.tv_name, Resource.Id.tv_time }); var listview = FindViewById<ListView>(Resource.Id.listView1); listview.Adapter = sam_adapter;
解释一下这里的List<IDictionary<string, object>>(),这就是为了新建一个数据对象,这里的JavaDictionary<string, object>()其实就是C#中的Dictionary<T,T>类型,这里就是添加数据。
在Android里面,类似这样的,都需要一个数据适配器,就是这里的listview.Adapter,我们通过FindViewById<ListView>,直接查找到给赋值就可以,在这里呢,用了一个相对复杂的 SimpleAdapter,其中第三个参数 Resource.Layout.layout_SimpleAdapter ,这个是自己定义的一个布局文件,当然,可以直接采取系统的布局文件,看下面代码。
var list = new List<string>() { "a.mp3", "b.mp3", "c.mp3" }; ArrayAdapter<string> a_adaper = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerItem, list);
如此,就可以看明白了吧,第一个参数this,意思就是当前活动的 Activity,第二个参数就引用了系统的布局。
2、Spinner
该控件提供了从一个数据集合中快速选择一项值的办法。默认情况下Spinner显示的是当前选择的值,点击Spinner会弹出一个包含所有可选值的dropdown菜单,从该菜单中可以为Spinner选择一个新值。同样,前面说到直接采用Adapter给赋值。如下。
var list = new List<string>() { "a.mp3", "b.mp3", "c.mp3" }; ArrayAdapter<string> a_adaper = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerItem, list); Spinner sp = FindViewById<Spinner>(Resource.Id.spinner1); sp.Adapter = a_adaper; sp.SetPromptId(Resource.String.Title);
这里的 SetPromptId 就是通过这个设置一个标题,这里呢,我是自己的 strings.xml 文件中定义的一个常量。
3、GridView
直接利用前面说到的数据控件 SimpleAdapter ,直接在界面上拖拽一个 GridView过来即可。
var list_dic = new List<IDictionary<string, object>>(); for (int i = 0; i < 8; i++) { var dic = new JavaDictionary<string, object>(); dic.Add("name", "Tel:" + i); dic.Add("icon", Resource.Drawable.Icon); dic.Add("time", DateTime.Now.Second + ":" + DateTime.Now.Millisecond); list_dic.Add(dic); } SimpleAdapter sam_adapter = new SimpleAdapter(this, list_dic, Resource.Layout.layout_SimpleAdapter, new string[] { "name", "icon", "time" }, new int[] { Resource.Id.tv_name, Resource.Id.tv_time }); var gv1 = FindViewById<GridView>(Resource.Id.gridView1); gv1.Adapter = sam_adapter;
还是同时通过适配器 Adapter 来绑定数据。
附:GridView的一些属性(其实百度随便就能找到)
使用android:numColumns设置列数
使用android:columnWidth设置每列宽度
如果把android:numColumns的值改成”auto_fit”,配合android: columnWidth能自适应。
使用android:horizontalSpacing设置没列间距
使用android:verticalSpacing设置每行间距
二、通信
通信在这里可能用的不太恰当,其实这个在前面已经提到了, Intent
1、基本跳转
我们首先来建立一个基本页面,来实现接收。
在layout文件夹上面选择添加新建项直接新建一个 Android Layout的页面。
这个页面的目的是为了当跳转过去之后确认成功。
接下来,我们添加一个新的 Activity。
为了界面的整齐,我们直接在项目上添加一个新建项。
目的是为和 MainActivity 处于目录下面,然后加入代码 SetContentView。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; namespace Test015 { [Activity(Label = "Activity2")] public class Activity1 : Activity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); //绑定视图 SetContentView(Resource.Layout.layout1); } } }
加上这个的界面的目的就是为了让有界面去接收。
在 MainActivity 的界面添加如下代码。
Intent it = new Intent(this, typeof(Activity1)); StartActivity(it); it.PutExtra("test", "Mono for Android"); StartActivity(it); Finish();
这里的 StartActivity 就是启动这个意图, 后面的 PutExtra 的目的就是传递一个 唯一标示为 name 的定量。然后,我们继续在 Activity1 这个页面添加代码,把传递过来的数据接收一下,打印出来。当然,要实现这个,我们还是要实现 IDialogInterfaceOnClickListener 的接口
Toast.MakeText(this, Intent.GetStringExtra("test"), ToastLength.Long).Show();
public void OnClick(IDialogInterface dialog, int which) { Toast.MakeText(this, which + "", ToastLength.Short).Show(); }
在跳转的 Activity 里面直接去接收就可以, 采用 Intent.GetStringExtra("test") ,通过这个唯一标示name获取这个变量。
直接启动就可以在虚拟机里面看到效果了。
2、实现隐式意图
在跳转的基础上,我们在 Activity1 的这个活动页面上,添加过滤器,这个过滤器的位置,要添加在 public class Activity1 : Activity ,IDialogInterfaceOnClickListener 这句代码的前面。
//创建隐式视图 //只处理和http有关系的 [IntentFilter(new string[] { Intent.ActionView }, Categories = new string[] { Intent.CategoryDefault }, DataScheme = "http")] public class Activity2 : Activity,IDialogInterfaceOnClickListener { public void OnClick(IDialogInterface dialog, int which) { Toast.MakeText(this, which + "", ToastLength.Short).Show(); } protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.layout1);
ImageButton ibtn = FindViewById<ImageButton>(Resource.Id.imageButton1); ibtn.Click += delegate { url(); }; } }
通过这里的注释我们就可以看明白,这个是什么意思了,这里就是添加一个打开 网页时的 隐式意图,比如我们的手机系统里面安装了好多个浏览器,我的手机里面不是有 UC浏览器,每次启动的时候,有一个检测,是不是默认浏览器,我们这个就是那个意思。下面的那个就是前面说到的实现的接口,和设置的绑定页面。
要实现这个,我们首先要有一个打开 url 的方法。 在我们前面添加的 layout1.axml 界面上添加一个按钮,这个按钮的目的就是实现一个 跳转的 意图,也就是显示我们这里的隐式意图的作用。在代码中添加单击事件(在这里不在赘述),和跳转代码。
private void url() { Intent it = new Intent(); it.SetAction(Intent.ActionView); it.SetData(Android.Net.Uri.Parse("http://www.baidu.com")); StartActivity(it); }
OK,到这里启动,当我们跳转过来,然后点击这个页面的时候,我们是不是可以有一个选择了。
三、广播
广播这个我不知道怎么解释了,简单的说一下,就是说,比如我们要打开软件的时候,然后直接跳转到开始界面的时候,某一些应用程序会告诉你,已经转到后台运行,这个广播的意思就是说,我们同样有这么一个唯一标示被监听,广播的目的就是监听事件。
具体可以参考:http://www.cnblogs.com/qianlifeng/archive/2011/03/06/1972305.html
我们直接添加一个项目。界面代码如下:
<?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"> <Button android:id="@+id/MyButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/Hello" /> <Button android:id="@+id/Register" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="注册广播" /> <Button android:id="@+id/Cancel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="取消注册" /> <Button android:id="@+id/Send" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="发送广播" /> <TextView android:text="Text" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="24sp" android:id="@+id/textView1" /> </LinearLayout>
后台的 MainActivity 代码如下:
using System; using Android.App; using Android.Content; using Android.Runtime; using Android.Views; using Android.Widget; using Android.OS; using Java.Util; namespace Test017 { [Activity(Label = "MyAPK", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : Activity { int count = 1; private ReceiveBroadCast receiveBroadCast; //广播实例 /// <summary> /// 拨号界面 /// </summary> private string flag = "android.intent.action.CALL_BUTTON"; protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); Button button = FindViewById<Button>(Resource.Id.MyButton); button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); }; //注册 Button btn_register = FindViewById<Button>(Resource.Id.Register); btn_register.Click += Btn_register_Click; //取消 Button btn_cancel = FindViewById<Button>(Resource.Id.Cancel); btn_cancel.Click += delegate { UnregisteLinster(); }; //发送广播 Button btn_send = FindViewById<Button>(Resource.Id.Send); btn_send.Click += Btn_send_Click; } private void Btn_send_Click(object sender, EventArgs e) { Intent intent = new Intent(); //Itent就是我们要发送的内容 intent.PutExtra("data", "this is data from broadcast " + DateTime.Now.ToString("yyyy-MM-dd HH:ss:mm")); intent.SetAction(flag); //设置你这个广播的action,只有和这个action一样的接受者才能接受者才能接收广播 SendBroadcast(intent); //发送广播 } private void UnregisteLinster() { UnregisterReceiver(receiveBroadCast); } /// <summary> /// 继承 /// </summary> public class ReceiveBroadCast : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { // //这里的目的是为了监听你的广播是否起作用了 // ProgressDialog p_dialog = new ProgressDialog(context); p_dialog.SetMessage("正在加载……"); p_dialog.Show(); } } private void Btn_register_Click(object sender, EventArgs e) { receiveBroadCast = new ReceiveBroadCast(); IntentFilter filter = new IntentFilter(); filter.AddAction(flag); //只有持有相同的action的接受者才能接收此广播 RegisterReceiver(receiveBroadCast, filter); } } }
我们直接运行,首先注册这个广播。然后点击发送广播,我们是不是就可以看到那个正在加载的提示信息了。
关于Android的四大组件 Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器。目前为止,我们已经说到了 Activity 和 BroadcastReceiver广播接收器。请待后续更新,因为我也是新手呀。
说点关于安装的这个东西,不知道 win 8是怎么了。我安装的 Android Studio, SDK Manager 和 AVD Manager是没有任何问题的,但是 Android Studio这个主界面启动不了,最后在win7的虚拟机上捣鼓了半天,可以了,在win xp上面试了一下,可能因为 jdk 文件版本的问题,运行不了。
额,凌晨两点了,有点饿了,希望大家伙看到 有点饿的面子上,欢迎指证错误、动起来您那可爱的小手,默默地给推荐一下,需要源码的同学可以留言。