正如你所见的,Android的XML布局文件是繁琐的,但却能让你控制到屏幕的各个元素。
在Android中最重要的接口元素是布局Layout容器,例如例子中使用的LinearLayout 。这些元素对于用户是不可见的,但是却扮演者例如Buttons 和TextViews这些元素的布局容器。
Android中有几种不同类型的布局视图layout view,每一种都用于开发不同的布局。如同LinearLayout 和AbsoluteLayout ,TableLayout 可以让你使用更为复杂的基于表格结构的布局。你可以在SDK的API文档的通用布局对象中查找到更多的布局。
关联你的布局Layout与代码
保存你的布局,在Eclipse中点击Run图标或按下Ctrl+F11重新在模拟器中运行你的程序。你现看到不是之前出现的Hello World消息了,你将看到Android显示了一个新的界面。
如果点击界面上的任何按钮,他们将期望的显示为高亮,但是不会执行任何操作。现在让我们在布局修改后改进一下我们的源码:
# /src/com/example/brewclock/BrewClockActivity.java
...
import android.widget.Button;
import android.widget.TextView;
public class BrewClockActivity extends Activity {
/** Properties **/
protected Button brewAddTime;
protected Button brewDecreaseTime;
protected Button startBrew;
protected TextView brewCountLabel;
protected TextView brewTimeLabel;
...
}
下一步,我们将修改调用onCreate。当Android启动你的应用程序的时候,Android会首先调用这个方法。 在Eclipse生成的代码中,onCreate把activity的视图设置成R.layout.main。这行代码告诉Android解释我们的布局配置XML文件,并显示它。
资源对象
在Android中,R是一个自动生成的对象,这是一个特殊的对象,你可以在代码中通过这个对象访问项目中的资源(布局,字符串,菜单,图标,…) 。每个资源都有一个给定的id。在上面的那个布局文件中,有一些@+id XML 属性。我们将通过这些值来关联布局中的Buttons 与TextViews和我们的代码和:
# /src/com/example/brewclock/BrewClockActivity.java
...
public class BrewClockActivity extends Activity {
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Connect interface elements to properties
brewAddTime = (Button) findViewById(R.id.brew_time_up);
brewDecreaseTime = (Button) findViewById(R.id.brew_time_down);
startBrew = (Button) findViewById(R.id.brew_start);
brewCountLabel = (TextView) findViewById(R.id.brew_count_label);
brewTimeLabel = (TextView) findViewById(R.id.brew_time);
}
}
监听事件
为了检测到用户单击我们的按钮,我们需要实现一个监听器listener。你可能会从其他的事件驱动系统中熟悉监听器或回调函数callbacks。比如Javascript/JQuery事件或Rails的回调函数。
Android通过Listener接口提供相似的机制,例如OnClickListener,这个接口中定义了那些会被事件触发的方法。当用户点击屏幕的时候,实现OnClickListener 接口将会通知你的应用程序,并告诉他们所按得屏幕按钮。你当然也需要告诉每个button的ClickListener,以便Android知道具体通知到那个监听器:
# /src/com/example/brewclock/BrewClockActivity.java
...
// Be sure not to import
// `android.content.dialoginterface.OnClickListener`.
import android.view.View.OnClickListener;
public class BrewClockActivity extends Activity
implements OnClickListener {
...
public void onCreate(Bundle savedInstanceState) {
...
// Setup ClickListeners
brewAddTime.setOnClickListener(this);
brewDecreaseTime.setOnClickListener(this);
startBrew.setOnClickListener(this);
}
...
public void onClick(View v) {
// TODO: Add code to handle button taps
}
}
下一步,我们将增加每个按钮按下的处理过程。我们将为Activity类增加4个属性,这些属性将用来让用户设置和记录我们泡茶时间,泡茶计数,计时器是否在运行的标志。
# /src/com/example/brewclock/BrewClockActivity.java
...
public class BrewClockActivity extends Activity
implements OnClickListener {
...
protected int brewTime = 3;
protected CountDownTimer brewCountDownTimer;
protected int brewCount = 0;
protected boolean isBrewing = false;
...
public void onClick(View v) {
if(v == brewAddTime)
setBrewTime(brewTime + 1);
else if(v == brewDecreaseTime)
setBrewTime(brewTime -1);
else if(v == startBrew) {
if(isBrewing)
stopBrew();
else
startBrew();
}
}
}
注意我们使用了Android提供的类CountDownTimer 。这让我们非常容易的创建和开始一个简单的递减计数,这个递减计数在递减运行的时候,每当执行一个递减就发出一个通知。你将在下面的startBrew 方法中使用到这个计数器。
在下面的方法是所有处理逻辑,这些处理逻辑用于处理设置泡茶时间,开始停止计数和维护计数器。我们同样地在onCreate方法中来初始化我们的 brewTime和 brewCount变量。
将这些代码放入到不同的类中是一种好做法。但是为了简洁,我把我们所有的代码都放到了BrewClockActivity中:
# /src/com/example/brewclock/BrewClockActivity.java
...
public class BrewClockActivity extends Activity
implements OnClickListener {
...
public void onCreate(Bundle savedInstanceState) {
...
// Set the initial brew values
setBrewCount(0);
setBrewTime(3);
}
/**
* Set an absolute value for the number of minutes to brew.
* Has no effect if a brew is currently running.
* @param minutes The number of minutes to brew.
*/
public void setBrewTime(int minutes) {
if(isBrewing)
return;
brewTime = minutes;
if(brewTime < 1)
brewTime = 1;
brewTimeLabel.setText(String.valueOf(brewTime) + "m");
}
/**
* Set the number of brews that have been made, and update
* the interface.
* @param count The new number of brews
*/
public void setBrewCount(int count) {
brewCount = count;
brewCountLabel.setText(String.valueOf(brewCount));
}
/**
* Start the brew timer
*/
public void startBrew() {
// Create a new CountDownTimer to track the brew time
brewCountDownTimer = new CountDownTimer(brewTime * 60 * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
brewTimeLabel.setText(String.valueOf(millisUntilFinished / 1000) + "s");
}
@Override
public void onFinish() {
isBrewing = false;
setBrewCount(brewCount + 1);
brewTimeLabel.setText("Brew Up!");
startBrew.setText("Start");
}
};
brewCountDownTimer.start();
startBrew.setText("Stop");
isBrewing = true;
}
/**
* Stop the brew timer
*/
public void stopBrew() {
if(brewCountDownTimer != null)
brewCountDownTimer.cancel();
isBrewing = false;
startBrew.setText("Start");
}
...
}
这段代码唯一和Android相关的就是使用setText方法来设置文本的显示文字。在startBrew方法中,我们创建,并开始了一个CountDownTimer来开每秒递减计数直到计数器为0。注意,我们定义了CountDownTimer以内联方式监听onTick 和 onFinish方法。 onTick 方法将每1000毫秒(1秒)执行一次,并递减, 当计数器为0的时候,onFinish方法被调用。
避免在你的代码中硬编码
为了使教程代码简单,我故意地在程序中将控件的标号直接写到字串中(例如: “Brew Up!”, “Start”, “Stop”) 通常,这不是一个好的做法,因为如果在大型项目中,这样做会使得修改变得麻烦。
Android 提供了一种简洁的方法让你使用R对象来使字符串和代码分离。R 让你在xml文件(res/values/strings.xml)定义所有你程序中字符串,并让你可以在代码中应用到这些字符串。例如:
# /res/values/strings.xml
Brew Up!
...
# /res/com/example/brewclock/BrewClockActivity.java
...
brewLabel.setText(R.string.brew_up_label);
...
现在,如果你想改变Brew Up! 字样,你只要一次性的修改strings.xml文件就行了。你的应用将生成一堆代码来保证你程序中所有使用到这些字符串的地方都能被生效!
运行Brew Clock
代码完成之后,现在是试运行程序的时候了。单击Run 或 Ctrl+F11 在模拟器中启动我们的应用. 所有都运行良好,你将会看到你创建的用户界面在准备时间一到就可以喝你所泡的茶了!试着设置不同的时间,并点击Start 观看倒计时。
总结
在这个关于Android的简单介绍中,你已学会如何安装Android SDK和Eclipse的Android 开发工具插件(ADT)。你也学会如何创建一个模拟设备,并通过这个设备来测试你的应用程序。你还学会了如何开发Android应用程序。上面了那些作为标题的关键概念在以后你自己开发Android应用程序的时候将会经常用到。
我们希望,这个教程能激发你的开发移动应用程序的欲望,并步入这个令人激动的领域。Android为当前和即将到来的移动设备应用程序开发提供了一条宽广的道路。如果你已经开发你自己的移动应用,请在评论中告诉我们。
(ik), (vf)