第1个Android应用程序 Android制作简单单页导航
作者:rainmj 发布时间:2022-09-27 22:23:26
本例子演示如何添加一个简单的单页导航,在此基础上,再演示如何在第2个页面中显示第1个页面中拨打过的所有电话号码。
(1)通过该例子理解Android App的基本架构。
(2)通过该例子理解实现Android多屏幕导航的基本技术。
本例子只是为了让我们对Android App开发有一个较全面的感性认识,读者不必一开始就纠结于代码中的细节问题,涉及到的相关概念在后面还会分别介绍。
运行截图
运行截图(Api19、Api21、Api23的实现代码都相同):
界面操作
单击“将文本转换为数字”,观察结果。
单击【转换】按钮,如果转换成功,则【拨号】按钮可用,单击【拨号】按钮,观察弹出的对话框。
如果单击【拨号】按钮,就会自动拨号。
下面介绍主要设计步骤。
1、新建项目
选择模板:Blank App (Android),项目名:PhonewordApp。
项目创建成功后,删除GettingStarted.Xamarin(广告文件)。
2、界面设计
(1)双击打开Main.axml,分别观察设计界面【Design】和源码【Source】的内容。
(2)按Delete键删除【Hello World,Click Me】按钮。
(3)从【工具箱】中拖放一个【Text (Large)】到设计界面,修改下面的属性:
id:@+id/PhoneText
text:电话
注:此时系统会自动在【Source】中添加对应的代码(下同)。
(4)从【工具箱】中拖放一个【Plain Text】到设计界面,放到【Text (Large)】的下方,修改下面的属性:
id:@+id/PhoneNumberText
text:138 4912 2599
(5)从【工具箱】中拖放一个【Button】到设计界面,放到【Plain Text】的下方,修改下面的属性:
id:@+id/buttonTranslate
text:转换
(6)从【工具箱】中拖放一个【Button】到设计界面放到上一个按钮的下方,修改属性:
id:@+id/buttonCall
text:拨号
经过以上步骤后,即得到下图所示的设计界面:
(7)保存文件,并单击【解决方案资源管理器】上方的【刷新】按钮。
注意:这一步的目的是为了让系统能找到设计界面内的资源并自动生成对应的ID,以便在后面键入C#代码时能看到与设计界面资源相关的智能提示。
3、编写C#代码
(1)鼠标右击项目名à添加类,在弹出的窗口中,选择【Class】模板,名称:PhoneTranslator.cs,如下图所示,单击【添加】按钮。
然后将PhoneTranslator.cs改为下面的代码:
using System.Text;
namespace PhonewordApp
{
public static class PhonewordTranslator
{
public static string ToNumber(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
{
return "";
}
else
{
raw = raw.ToUpperInvariant();
}
var newNumber = new StringBuilder();
foreach (var c in raw)
{
if ("- 0123456789".Contains(c))
newNumber.Append(c);
else
{
var result = TranslateToNumber(c);
if (result != null)
newNumber.Append(result);
}
}
return newNumber.ToString();
}
static bool Contains(this string keyString, char c)
{
return keyString.IndexOf(c) >= 0;
}
static int? TranslateToNumber(char c)
{
if ("ABC".Contains(c))
return 2;
else if ("DEF".Contains(c))
return 3;
else if ("GHI".Contains(c))
return 4;
else if ("JKL".Contains(c))
return 5;
else if ("MNO".Contains(c))
return 6;
else if ("PQRS".Contains(c))
return 7;
else if ("TUV".Contains(c))
return 8;
else if ("WXYZ".Contains(c))
return 9;
return null;
}
}
}
(2)打开MainActivity.cs,将该文件改为下面的代码:
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Collections.Generic;
namespace PhonewordApp
{
[Activity(Label = "PhonewordApp", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
static readonly List<string> phoneNumbers = new List<string>();
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
var phoneNumberText = FindViewById<EditText>(Resource.Id.PhoneNumberText);
var buttonTranslate = FindViewById<Button>(Resource.Id.buttonTranslate);
var buttonCall = FindViewById<Button>(Resource.Id.buttonCall);
buttonCall.Enabled = false; //禁用【拨号】按钮
string translatedNumber = string.Empty;
buttonTranslate.Click += (s, e) =>
{
translatedNumber = PhonewordTranslator.ToNumber(phoneNumberText.Text);
if (string.IsNullOrWhiteSpace(translatedNumber))
{
buttonCall.Text = "拨号";
buttonCall.Enabled = false;
}
else
{
buttonCall.Text = "播出号码:" + translatedNumber + ",单击确认!";
buttonCall.Enabled = true;
}
};
var buttonCallHistory = FindViewById<Button>(Resource.Id.buttonCallHistory);
buttonCallHistory.Click += (sender, e) =>
{
var intent = new Intent(this, typeof(CallHistoryActivity));
intent.PutStringArrayListExtra("phone_numbers", phoneNumbers);
StartActivity(intent);
};
buttonCall.Click += (s, e) =>
{
phoneNumbers.Add(translatedNumber);
buttonCallHistory.Enabled = true;
// 当单击【拨号】时,尝试拨号
var callDialog = new AlertDialog.Builder(this);
callDialog.SetMessage("电话:" + translatedNumber + ",拨号吗?");
callDialog.SetNeutralButton("拨号", delegate
{
var callIntent = new Intent(Intent.ActionCall);
callIntent.SetData(Android.Net.Uri.Parse("tel:" + translatedNumber));
StartActivity(callIntent);
});
callDialog.SetNegativeButton("取消", delegate { });
callDialog.Show();
};
}
}
}
(3)重新生成项目,确保无错误。
注:drawable文件夹下的Icon.png是要显示的图标,也可将其换为其他图标文件。
(4)选择主菜单下该项目的属性,在弹出的窗口中,勾选【CALL PHONE】权限:
注:
(1)这一步必须做,否则因该App无拨号权限,拨号功能会失败。
(2)设置后,查看Properties文件夹下AndroidManifest.xml文件中自动添加的代码,理解权限设置的作用。
4、调试运行及代码片段解释
选择一种模拟器,然后按<F5>键调试运行。
注意:如果使用低于API 23的模拟器,必须设置项目属性(主菜单à项目属性),使用对应版本的API来编译应用程序,否则在模拟器上运行时可能会出现应用程序一闪就退出或者显示“应用程序已停止运行”的情况。
下面解释前面已经实现的代码片段的含义:
(1)如何显示Alert对话框
AlertDialog的详细用法见【第6章 UI设计(三)--对话框】。
(2)如何拨号
下面的代码演示了如何调用系统功能实现拨号:
var callIntent = new Intent(Intent.ActionCall);
callIntent.SetData(Android.Net.Uri.Parse("tel:" + translatedNumber));
StartActivity(callIntent);
注意:运行前需要先勾选【CALL PHONE】设置允许拨号权限,否则运行会出现异常:
5、创建第2个屏幕跟踪历史记录
(1)打开values文件夹下的Strings.xml文件,添加下面的代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
……
<string name="CallHistory">拨号记录</string>
</resources>
(2)单击【解决方案资源管理器】上方的“刷新”按钮,或者重新生成项目。
注:选择其中之一即可,目的是为了让C#代码能识别它。
(3)打开Main.axml,从【工具箱】中拖放一个【Button】到Main.axml设计界面,将其放到上一个按钮的下方,修改属性:
id:@+id/buttonCallHistory
text:@string/CallHistory
enabled:false
注: @string/CallHistory的含义是在values文件夹下的Strings.xml文件中提供该变量的值。
此时,可看到“STRING/CALLHISTORY”会自动变成“拨号记录”。
说明:这一步设置变量值的做法是实际的Android App项目中建议的做法,这样做的好处是能提高安卓App运行的效率。而步骤1的做法是一种硬编码的做法,硬编码在安卓App中不是建议的做法,步骤1只是为了刚入门时理解更容易。
(4)鼠标右击项目名,选择【添加…】à【新建项】,在弹出的窗口中,选择“Activity”模板,文件名:CallHistoryActivity.cs,单击【添加】。然后将该文件改为下面的内容(省略了using……):
namespace PhonewordApp
{
[Activity(Label = "CallHistoryActivity")]
public class CallHistoryActivity : ListActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
var phoneNumbers =
Intent.Extras.GetStringArrayList("phone_numbers") ?? new string[0];
this.ListAdapter = new ArrayAdapter<string>(this,
Android.Resource.Layout.SimpleListItem1, phoneNumbers);
}
}
}
其中,c = a??b; 的含义相当于:if (a != null ){ c = a;} else { c = b;}
(5)修改MainActivity.cs文件,目标是收集第1个屏幕界面运行时拨打过的所有电话号码,并将其在第2个屏幕上显示出来。在MainActivity.cs文件中添加下面的代码:
……
using System.Collections.Generic;
namespace E01PhonewordApp
{
[Activity(Label = "E01PhonewordApp", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
static readonly List<string> phoneNumbers = new List<string>();
protected override void OnCreate(Bundle bundle)
{
……
var buttonCallHistory =
FindViewById<Button>(Resource.Id.buttonCallHistory);
buttonCallHistory.Click += (sender, e) =>
{
var intent = new Intent(this, typeof(CallHistoryActivity));
intent.PutStringArrayListExtra("phone_numbers",
phoneNumbers);
StartActivity(intent);
};
buttonCall.Click += (s, e) =>
{
phoneNumbers.Add(translatedNumber);
buttonCallHistory.Enabled = true;
// 当单击【拨号】时,尝试拨号
var callDialog = new AlertDialog.Builder(this);
callDialog.SetMessage("播出号码:" + translatedNumber +
",拨号吗?");
callDialog.SetNeutralButton("拨号", delegate
{
// Create intent to dial phone
var callIntent = new Intent(Intent.ActionCall);
callIntent.SetData(Android.Net.Uri.Parse("tel:" +
translatedNumber));
StartActivity(callIntent);
});
callDialog.SetNegativeButton("取消", delegate { });
callDialog.Show();
};
}
}
}
(6)重新生成项目,确保无错误。
(7)运行,再拨一个号(例如12345678901),然后查看拨号记录。下图是用另一种模拟器查看的运行效果(你可以创建多种不同的模拟器,分别观察同一个项目的运行效果):
到这里,我们就完成了用C#编写的第1个Android应用程序。
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- 这篇文章主要介绍了如何使用Jenkins编译并打包SpringCloud微服务目录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有
- 一.优先队列的应用优先队列在程序开发中屡见不鲜,比如操作系统在进行进程调度时一种可行的算法是使用优先队列,当一个新的进程被fork()出来后
- 下图是《Unity Shader 入门精要》一书中的渲染流程图;ApplicationStage阶段:准备场景信息(视景体,摄像机参数)、粗
- 本文实例讲述了Android开发中MotionEvent坐标获取方法。分享给大家供大家参考,具体如下:Android MotionEvent
- 一、问题定义:问下有一个数组,这些数组中的值都有自己的权重,怎样设计才能高效的优先取出权重高的数??例如:权重: 8 2&nbs
- 问题在本地启动dubbo时,服务注册在本地的zookeeper ,但是注册IP却不是本地的iP。产生问题,导致consumer 找不到pro
- 一、 应用程序直接建立数据库连接模型应用程序直接每次访问数据库时,都建立创建一个数据库的链接,这样每次建立这样的连接都需要耗费的资源,当同时
- 主要从以下几方面来介绍一下@Scope注解@Scope注解是什么@Scope注解怎么使用@Scope注解的使用场景1,@Scope注解是什么
- java 中遍历取值异常(Hashtable Enumerator)解决办法用迭代器取值时抛出的异常:java.util.NoSuchEle
- 写在前面 众所周知,kafka是现代流行的消息队列,它使用经典的消息订阅发布模式实现消息的流转,大部分代码结合kaf
- 本文实例讲述了Android TextView中文字通过SpannableString设置属性的方法。分享给大家供大家参考,具体如下:在An
- 我们开发一个Spring Boot项目,肯定要导入许多的静态资源,比如css,js等文件如果我们是一个web应用,我们的main下会有一个w
- 相信大家肯定都在电商网站买过东西,当我们看中一件喜欢又想买的东西时,这时候你又不想这么快结账,这时候你就可以放入购物车;就像我们平时去超市买
- 使用范围: 只能作用在方法和构造函数之上@SneakyThrows注解的作用得从java的异常设计体系说起。java中常见的异常有两种:Ex
- 在JDK的Collection中我们时常会看到类似于这样的话:例如,ArrayList:注意,迭代器的快速失败行为无法得到保证,因为一般来说
- 相信对于打印三角形都没什么难度,只需要利用for循环嵌套使用就行但是对于打印圆形和三角形不同因为到圆心距离相等的点一般不会横坐标和纵坐标都为
- 本文实例讲述了C#实现的WINDOWS登录功能。分享给大家供大家参考,具体如下:using System;using System.Data
- 实践过程效果代码public partial class Form1 : Form{ public Form1()
- 应用开发的时候,有时我们需要将一些图片进行预览,例如:相片管理的应用。这个时候用ListView的话就显得不是太合适了,因为Li
- 最近接触到个新项目,发现它用了一个比较有意思的框架,可以说实现了我刚入行时候的梦想,所以这里马不停蹄的和大家分享下。在我刚开始工作接触的项目