在小学的作文课上,语文老师时常会强调作文提纲的重要性。对于程序创建也是如此,当一个具备Java基础的开发者,在搭建好OPhone平台之后,希望在实践中学习开发,却无从下手。找到一个开发实例不是难事,但是你会很好奇代码的创作者是怎样一步步使想法变成需求,怎样把纸上的说明文档编写成代码,怎样在程序出现故障的时候分析和调试等。
在本章中,我们站在开发者的视角带领大家经历程序的创作和开发的流程,而不是用冗长的原理来打击读者积极性,并在此基础上学习令他们困惑的代码。读者可以经历从需求分析到项目总结的流程,在实践中去查阅自己需要的资料,使用调试器排除万难,并在成功创建程序之后总结收获心得。
程序设计初探
一、 Ophone程序需求分析
首先,我们要和读者一起开发一个体质指数的软件,即根据用户输入的身高或体重数据,给出健康参考信息。
软件需要满足用户的3个需求:
1、根据体重给出身高的正常范围。
2、根据身高给出体重的正常范围。
3、输入身高和体重,给出健康参考建议。
在用户界面上,用户提出如下需求:
1、3个需求分别用3个界面实现,3个界面之间可以在菜单中自由切换。
2、对于第3个需求,需要在界面上显示健康建议,并可实现建议的暂存。
3、支持多个测量单位,如磅(pt)、公斤(kg)、英尺(ft)、米(m)。
4、身高或者体重数据采用文本框输入,单位采用下拉列表输入,性别采用单选按钮输入。
二、Ophone程序设计流程
首先我们上网查找关于身高体重指标的知识:
某指标认为,女性的标准体重是:身高(cm)-105=标准体重(kg),男性的标准体重是:身高(cm)-100=标准体重(kg)。
例如,一个身高160cm的女子,她的标准体重应该是:160(cm)-105=55(kg)。凡是超过标准体重10%者为偏重,超过标准体重20%者为肥胖,低于10%者为偏瘦,低于20%者为消瘦。测量单位换算公式:1m=3.28ft,1kg=2.2pt。
根据用户需求绘制出界面的框架,如图2-1所示。
先别忙动手写代码,这虽然是个小程序,但是3个界面的切换也会让一个新手无从下手。一般来说,实现界面切换有如下几种方法:
1、通过选择功能界面来确定某个控件的显示或隐藏,这是最简单但是最不易维护的办法。
2、编写3个程序,在切换界面时互相调用实现切换,这是比较简单的办法,但是使用中会消耗更多的资源。
3、应用程序通过装载不同的main.xml文件实现界面的变化,这样可以使程序看上去更加清晰,但是控件初始化以及用户输入的获取需要提取共性。
三、Ophone程序代码实现
再来分析用户的需求,我们可以发现,在体重参考和身高参考两个界面中,唯一不同的地方就是计量单位不同,一个是输入身高输出体重参考,一个是输入体重输出身高参考;健康参考界面和前两个界面的差别略大。完成该程序的流程如图2-2所示。
先不要忙着想界面的切换,我们首先做一个单界面的程序,用来实现用户的第一个需求:根据体重给出身高的正常范围。通过这个程序的编写,我们可以熟悉界面设计、控件响应、方法调用。
在新建一个工程之后,双击res/layout/main.xml文件,出现可视化XML编辑器界面。将控件拖入屏幕区域,实现如图2-3所示结构,用鼠标右键单击该控件选择“Properties”,可以设置控件属性。这里LinearLayout01的orientation是垂直的(Vertical),LinearLayout02是水平的(Horizontal)。可以通过设置控件的Text属性来修改控件上显示的文字,将EditText01的Input Type属性改成Input type numberDecimal,使其只能输入数字(含小数),在代码中无需进行数字字符判断。编辑完成后,界面效果如图2-4所示。
运行该工程,就可以看到界面,但是单击“查看”按钮什么都没有发生。而且在单选按钮中选项都没有被选中。我们回到Eclipse中,将RadioButton01的Checked属性选择为True,并在代码编辑器窗口填写下列代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] str={"男","女"};
final Spinner gender = (Spinner) findViewById(R.id.Spinner01);
ArrayAdapter adapter = new ArrayAdapter(
this, android.R.layout.simple_spinner_item, str);
adapter.setDropDownViewResource(android.R.
layout.simple_spinner_dropdown_item);
gender.setAdapter(adapter);
Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
TextView tv = (TextView)findViewById(R.id.TextView01);
EditText data = (EditText)findViewById(R.id.EditText01);
RadioButton kg = (RadioButton)findViewById(R.id.RadioButton01);
float wt =Float.valueOf(data.getText().toString());
float h1,h2;
if (!kg.isChecked()) wt=(float) (wt/2.2);
if(gender.getSelectedItem().toString().equals("男")) {
h1 = (float) (wt*0.9+100);
h2 = (float) (wt*1.1+100);
}else {
h1 = (float) (wt*0.9+105);
h2 = (float) (wt*1.1+105);
}
tv.append("身高范围是:"+String.valueOf(h1)+"米--"+
String.valueOf(h2)+"米"+"\n");
}
});
}
运行工程,可以看到如图2-5所示结果。
四、Ophone程序代码分析
完成了第一个具有“实用价值”的程序是不是觉得有一些兴奋?还是有更多的疑问?如果你具备基本的编程基础,我相信你最陌生的莫过于“适应”了。ArrayAdapter是一个数组适配器,它可以将某种类型的数据数组(在这里是字符串数组)和列表相关联。这个列表在这里是称为spinner的控件,也可以是List形式的控件。作比喻如下:adapter好比是房产中介,字符串数组str好比是房东向中介提供的原始房源信息,中介可以将这些房源信息制成精美的图片广告单贴在玻璃门上,也可以用粉笔抄写在小黑板上,是玻璃门还是小黑板取决于函数setDropDownViewResource的参数。
下拉框的外观也有两种,android.R.layout.simple_spinner_item 和simple_spinner_ dropdown_item,有兴趣的读者可以在代码中轮流使用这两种spinner外观。
在本例中,我们使用了大量的LinearLayout,并且指定其上的控件为水平或者垂直分布。我们可以把Layout想象成一个托盘,所有的菜肴都放在这个托盘上,而LinearLayout只是其中一种形状的托盘。Layout用来控制控件在屏幕上的位置,并且能相互嵌套创建任意复杂的界面。下面是几种常见的Layout。
1、FrameLayout:最简单的Layout,FrameLayout将每一个控件显示在左上角。新增的控件将会覆盖掉前一个控件,把它们部分或全部挡住(除非它是透明的)。
2、LinearLayout:用来沿着某一个直线方向增加控件,其orientation属性包括垂直的和水平的。垂直的Layout每一行有一个控件;而水平的Layout每一列有一个控件。LinearLayout可以为每个控件指定“权重”,来控制在可获得的空间里每个控件的相对大小。
3、RelativeLayout:顾名思义,RelativeLayout用来定义每个控件相对于其他控件或屏幕边界的位置。例如,以右对齐、置于屏幕中央等形式来排列控件。
4、TableLayout:如果你具有设计制作网页的经验,TableLayout会给你带来似曾相识的感觉。它允许你按照网格的行列来放置控件。每格可以占据多个行和列,并且每列可以设定为缩小或增长。
5、AbsoluteLayout:在AbsoluteLayout里,每个控件的位置以绝对坐标进行定义。使用这个类,你可以为组件安排最精确的布局,但是它不能为不同的屏幕分辨率和方向进行动态调整。