Android(Xamarin)之旅(四)

这么晚了,可能也因为一点事情,就说打开博客园看看,结果 http://www.cnblogs.com/mindwind/p/5125248.html 这篇文章瞬间吸引了我。暗暗的回想一下,十年之后,我是什么样子,还是那样吗?为了生计奔波,为了那点渺茫的未来去争取……

在写这个的时候,我突然发现,我写的上一篇 三,竟然被转载了,哈哈,欢迎技术交流。

  今天我们主要说一下其他的数据组件、广播、服务。

一、数据组件

  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 文件版本的问题,运行不了。

    额,凌晨两点了,有点饿了,希望大家伙看到 有点饿的面子上,欢迎指证错误、动起来您那可爱的小手,默默地给推荐一下,需要源码的同学可以留言。

原文地址:https://www.cnblogs.com/JeffController/p/5132170.html