新的一年,新的开始,2016,我要做什么,大家要做什么,啦啦啦。
OK,上篇已经介绍了几个简单的控件,这次,我们继续说说控件。但是可能有人认为这有什么难的,问题不在这里,而在于,如果你注意了每一个空间,或者你就会发现,在很多的应用里面,很多的玩意都是直接用的控件。
一、Visual Studio 工具箱布局
1、Other Widgets 这里就一个Switch,其实也就是一个开关布局
2、Images & Media 这里面的有ImageButton、ImageView、MediaController、VideoView等等。这里的这些就是引用的一些基本的播放器,可以直接从字面意思领略。
3、Layouts 布局我就不说了
4、Composite 通俗的说,这里面的基本上都是类似列表的的那种控件,比如,ExpandableListView可以做一个手风琴那样的样式 (http://blog.csdn.net/gyflyx/article/details/6461242) 再如ListView,也就是一个简单的风格 (http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html) GridView (http://www.cnblogs.com/tinyphp/p/3855224.html)。。 等等。
5、Advanced 里面的这些我还没有看,不过感觉还是和布局有关的。
6、Form Widgets 这里面就是一些常用的,比如button、text、checkbox等等。
7、Text Fields 如E-mail( http://www.2cto.com/kf/201209/153859.html ),Password这类的,怎么说,感觉这个就属于和系统交互数据的那部分组件。
8、Time & Date 这里的包含了日期控件和时间控件等等。
9、Other Layouts 从字面意思就能理解这是其他的布局了
感觉写了这些没什么作用,还是直接说怎么用吧。 百度网盘API下载:http://pan.baidu.com/s/1hqUeF6O
这些个API可以直接查询,比如,我要查询前面说到的ImageButton
我们可以直接通过API来查询,来找一些属性,写代码应该都是这个道理了,写的多了,理解了,也就记住了。
二、控件
<ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/imageView1" />
这里这么写的目的是为了介绍几个方法:
①、SetImageDrawable
private void Set_iv_url() { ImageView iv1 = FindViewById<ImageView>(Resource.Id.imageView1); iv1.SetImageDrawable(Resources.GetDrawable(Resource.Drawable.myapk)); }
这里的SetImageDrawable这里访问的Resorce,也就是说访问的是
如图,也就是说我这里的写法是直接通过在Resources的文件夹下面的drawable来访问的,因为只要是资源文件,都有一个ID,也就是这里的resID,但是肯定发发现上面还有一个level.
②、SetImageLevel
道理也是一样,但是这里传递的就是
iv1.SetImageLevel(Android.Resource.Drawable.AlertDarkFrame);
也就是说这里的这个引用的是系统的资源,而不是上面的那个我们拷贝进去的资源,当然,还有一些,比如SetImageBitmap,直接按照正常的写法写就可以了。
<CheckBox android:text="是否显示" android:layout_width="match_parent" android:layout_height="wrap_content" android:checked="true" android:id="@+id/cb_test" />
这个我们就看一下CheckBox选中就可以,但是怎么在界面上得到这个值呢。
CheckBox cb = FindViewById<CheckBox>(Resource.Id.cb_test); cb.CheckedChange += Cb_CheckedChange;
因为在Android所有的界面元素都要去寻找,所以强转是每一步必须要写的。
/// <summary> /// 是否选择,选择提示框 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Cb_CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e) { //e.CheckedId //是否选中 Toast.MakeText(this, e.IsChecked.ToString(), ToastLength.Long).Show(); }
这里可以看到Toast.MakeText这个方法,是需要添加命名空间 Android.Widget 的,当然引用都一样,直接 using就可以了,至于里面的ToastLength是一个内置的枚举值,后面的Show()方法,才是重点,就是这个,才能打印到界面上,可以尝试一下。
关于这个控件,大家应该能猜测是什么了,直接拖到界面上,你就晓得了,然后把里面的RadioButton的值变一变什么的,你懂的
private void Rb_RatingBarChange(object sender, RatingBar.RatingBarChangeEventArgs e) { Toast.MakeText(this, e.CheckedId.ToString(), ToastLength.Long).Show(); }
当然了,这个组件也是CheckedChange这个方法,直接调用这个方法,然后写一个方法,委托给它就好。其中,因为这个是一组RadioButton,我们通过现在的CheckedId可以获取到的就是如下这个ID,有了这个ID,我们又可以做很多事情了,啦啦啦。
为什么要直接这么说呢,大家直接在工具栏就可以看到 Time & Date,就在那里面你一个个的去脱,就知道了。
1、AnalogClock 就是一个石英表的表盘,直接拖过来就能看到效果的。
2、DigitalClock 这个呢,是一个数字时钟,可以调解为24小时制的,也可以是上午下午的那种。
3、TimePicker 这就是一个时间控件。作为时间控件,那么我们首先肯定要获取到。
TimePicker tp = FindViewById<TimePicker>(Resource.Id.timePicker1); tp.SetIs24HourView(Java.Lang.Boolean.True); tp.TimeChanged += Tp_TimeChanged;
在这里,一定要注意 SetIs24HourView() 这个方法,尼玛,各种坑爹,也就是说这个方法本来的值其实也就是true或者false,但是在这里传递的时候,必须是 Java.Lang.Boolean.True ,Ok,说到这里,请大家一定要注意,这就是个坑,
在Vs2015里面,只要是加了Java,好么,你就照着写就行,别想那么多,虽然我们都明白Boolean和Bool一个德行,但是呢,你懂的。
private void Tp_TimeChanged(object sender, TimePicker.TimeChangedEventArgs e) { int hour = e.HourOfDay; int min = e.Minute; Toast.MakeText(this, hour.ToString() + ":" + min.ToString(), ToastLength.Short).Show(); }
如上,直接通过代码获取值就可以了。不过可能因为虚拟机的关系,我的反应还是相当慢的,但是放到实体机器上面,效率还是不错的。
如图,在红色框里面的信息就是我们的Toast.MakeText方法,Show()之后得到的效果,还是不错的么,哈哈。
相信我,当我把这个空间拉倒页面上的时候,我瞬间惊呆了,尼玛,这不就是订餐软件的打分、诸如天猫、京东此类的打分么,我的个神呀。
OK,我们说说,怎么获取吧,看代码
RatingBar rb = FindViewById<RatingBar>(Resource.Id.ratingBar1); rb.Rating = 13f;//分数 rb.RatingBarChange += Rb_RatingBarChange;
private void Rb_RatingBarChange(object sender, RatingBar.RatingBarChangeEventArgs e) { if (e.FromUser) { Toast.MakeText(this, e.FromUser + "--" + e.Rating, ToastLength.Short).Show(); } }
其他的我就不说了,就说一下这里的FormUser的意思就是是否认为改变,意思就是到底是不是有效操作了,Rating,注释也加了,分数,相信自己运行一下,你们有没有感觉其实我们也是很叼的样子。
ToggleButton和Switch都有点开关的样子,我也没有具体看,直接就跳过了,看下效果图。
直接来界面代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/et_sms_per" android:inputType="phone" android:textSize="48px" android:hint="联系人" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/et_sms_content" android:inputType="phone" android:textSize="48px" android:hint="请输入内容" /> <!--wrap_content:包裹内容--> <ImageButton android:src="@drawable/resizeApi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/img_btn_sms" /> </LinearLayout>
顺便说下这里面可以的 xmlns:android="http://schemas.android.com/apk/res/android" 这一段申明绝对不能漏掉,看效果图。
顺便说下,这个图片是网上找的,随便找了一个,不要问我为什么,额,就这样。
后台代码:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); //获取button ImageButton img_btn_sms = FindViewById<ImageButton>(Resource.Id.img_btn_sms); img_btn_sms.Click += delegate { btn_Send(); }; } private void btn_Send() { //要发送的对象 EditText et_per = FindViewById<EditText>(Resource.Id.et_sms_per); //要发送的内容 EditText et_content = FindViewById<EditText>(Resource.Id.et_sms_content); //执行发送 //获得默认的消息管理器 SmsManager smsManager = SmsManager.Default; if (!string.IsNullOrEmpty(et_per.Text)) { if (!string.IsNullOrEmpty(et_content.Text)) { //拆分信息 IList<string> list = smsManager.DivideMessage(et_content.Text); //循环发送 foreach (string str in list) { //发送短信 smsManager.SendTextMessage(et_per.Text, null, str, null, null); //显示发送成功 Toast.MakeText(this, "发送成功!!", ToastLength.Long).Show(); } } else { //没有短信内容 Toast.MakeText(this, "没有短信内容!", ToastLength.Long).Show(); } } else { //显示发送成功 Toast.MakeText(this, "没有填写联系人!", ToastLength.Long).Show(); } }
简单的解释一下,首先,我们要用到Android.Telephony,这个就是发短信的管理器,必须要用到这个系统运用。也就是SmsManager。
短信有一个弊端,也就是说不能大于70字,理论值是这样,那么我们在这里采用DivideMessage() 这个就是用来拆分消息,拆分成多条,但是,问题就来了,用户接受到的肯定是多条短信,于是呢,就有了 sendMultipartTextMessage() 这个方法,这个的目的就是说短信发送的时候其实还是70个字这样的截取的,收费还是这么收费的,但是,在接收的时候,我们看到的是一条短信,至于到底为什么这样,额,这个问题,对于我来说,有点高深,我也是百度的。。虽然我已经亲自测试这个方法可用。
接下来就说说我发短信遇到的问题吧,刚有代码是不够的,首先,因为我本地下载的是 API23 和API 15,大爷的,每次默认的都是建立的API23的程序,但是我只有一个API15的虚拟机,所有说,第一次都么有启动起来。
打开AVD Manage可以看到我们现在建立的虚拟机到底是那个版本,然后 程序→右键→属性
先看下是不是匹配,然后再继续,问题又来了,就像我们操作Android手机一样,不是有一个root么,也就是说要有权限,坑爹呀,同样,右键属性
对,就是这里,权限勾选上,OK,终于成了。
打电话相对而言就简单了。同样的,写一个EditText,获取要拨打的电话号码,然后写一个Button就可以
后台代码
Button button = FindViewById<Button>(Resource.Id.MyButton); button.Click += delegate { btn_Call(); };
private void btn_Call() { /* 基本上所有的通信都是属于Intent 所有的数据都要从 StartActivity执行 这是一个活动的页面 报错:权限问题 既CALL_PHONE的权限(右键→属性→Android Mainifest) */ EditText et_num = FindViewById<EditText>(Resource.Id.tel_num); //调用系统的拨打号码界面 //必须是 tel 开头的 Intent intent = new Intent(Intent.ActionCall, Android.Net.Uri.Parse("tel:" + et_num.Text)); //启动拨打界面 StartActivity(intent); }
我想这个我就不解释了,直接看注释,我也是百度的,一个个慢慢找,心累。
OK,本次就到这里,希望大家动动您的双手,给小弟点个赞,或者给点宝贵意见也可以。
附: Android(Xamarin)之旅(一)