本文由Chris Blunt發表在smashingmagazine,bill學習之後,覺得與國内衆多Android入門教程相比,此文堪稱經典,鑒于有些朋友對Android非常感興趣卻遲遲找不到好的入門文章,在此特向大家推薦這篇博文。
<a href="http://coding.smashingmagazine.com/2010/10/25/get-started-developing-for-android-with-eclipse/">http://coding.smashingmagazine.com/2010/10/25/get-started-developing-for-android-with-eclipse/</a>
希望Chris Blunt的這篇文章能夠帶領更多的人進入Android的開發世界。
為了與一些對英文不太感冒的Android愛好者一起學習,同時也為了提高一下自己的語言表達、組織能力,特将全文翻譯過來供大家學習參考。
譯文bill已字字斟酌,但限于本人學識有限,譯文中可能出現術語或者習語翻譯不當甚或有錯,希望讀者積極指出,bill會非常高興收到你們的回報,在此謝過。
這個測試應用程式倒是工作的蠻不錯,但你總得建立自己的真正的應用吧?基于此,我們将通過一個簡單的應用設計,帶領你一步一步地學會開發Android應用并使它在Android裝置上運作。
如你所知,許多開發者(包括我在内)都喜歡在工作之餘泡上一杯好茶(或者咖啡)。在接下來的小節中,我将帶領你建立一個簡單的tea counter應用,用于記錄目前為止這個使用者一共沖泡了幾杯茶,并允許他們為自己的沖泡設定一個倒計時提醒。
在建立任何Android應用之前,我們總需要先設計并建立使用者界面。
下面是這個應用界面的一個預覽:
<a href="http://blog.51cto.com/attachment/201201/151045472.jpg" target="_blank"></a>
使用者可以通過“+”,“-”按鈕設定沖泡時間(以分為機關)。當他們點選“Start”按鈕,沖泡倒計時便開始啦。
除非使用者再次點選該按鈕以取消倒計時,那麼當倒計時完成時,沖泡的杯數就會自動加1。
Android的使用者界面(或者說用XML文檔描述的layouts)被儲存于項目中的res/layouts檔案夾。在之前的示例應用中那個顯示“Hello World”的簡單界面由Eclipse自動生成并儲存于res/layouts/main.xml中。
Eclipse也提供了圖形化界面設計器,它允許你對這些界面元素進行拖拽編排。盡管如此,我還是覺得在XML文檔中手動編寫界面,然後在圖形化界面設計器中預覽我編寫的界面更簡單易行。
現在,讓我們修改main.xml文檔以便使其展現出我們剛才設計的那個界面。
①在Eclipse的項目浏覽器中,輕按兩下打開res/layouts/main.xml文檔
②選擇main.xml的XML視圖示簽
現在,将XML文檔中的内容修改如下【bill注:最好自己手動寫一遍】
<?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">
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:padding="10dip">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="20dip"
android:text="Brews: " />
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="None"
android:gravity="right" android:textSize="20dip" android:id="@+id/brew_count_label" />
</LinearLayout>
android:layout_weight="1" android:gravity="center" android:padding="10dip">
<Button android:id="@+id/brew_time_down" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="-"
android:textSize="40dip" />
<TextView android:id="@+id/brew_time" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="0:00"
android:textSize="40dip" android:padding="10dip" />
<Button android:id="@+id/brew_time_up" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="+"
<Button android:id="@+id/brew_start" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_gravity="bottom"
android:text="Start" />
</LinearLayout>
正如你所見,Android的XML布局檔案非常備援,但卻能夠幫助你掌控螢幕上幾乎所有的視覺因素。
在Android布局檔案中一個重要的布局元素是——布局容器(布局方式),比如這個例子中的線性布局(LinearLayout)。這種布局對使用者是不可見的,隻作為那些可見的,諸如按鈕、文本框等視覺元素的容器。
當你完成布局檔案的編寫之後,再次運作這個應用,你會發現界面已經不是剛才那個簡單的“hello world”了,取而代之的是我們為這個應用設計的使用者界面。
如果你現在點選界面中的按鈕,你會發現他們會表現得和你預期的一樣——高亮顯示,但是,他們不會為你做任何事情。
下面讓我們來編寫代碼,使得點選界面按鈕時有适當的事情發生。
# /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系統啟動你的應用,這個方法就會被調用。在Eclipse自動生成的onCreate()實作中,将我們的應用布局設定成了R.layout.main。正是這一行代碼告訴Android系統将我們的layout布局檔案譯碼并展現給使用者。
在Android中,R類是一個特殊的資源類,允許你在自己的java代碼中通過它通路項目資源(布局layouts,字元串strings,菜單menus,圖示icons等等)。每一個資源都被賦予了一個ID,在上面的res/layouts/main.xml布局檔案中,通過“@+id”這一屬性實作。我們将利用這一屬性将布局檔案中的按鈕或者文本;連接配接到我們的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);
}
}
為了能夠得知使用者在何時點選了我們的按鈕,我們必須實作一個監聽器。你可能會覺得這很像其他擁有事件驅動的平台的listemers或者callbacks,就像Javascript/JQuery的events或者Rail的callbacks。
Android通過監聽器接口向我們提供了一個類似的機制。比如OnClickListener接口定義了一個當某事件發生時會被觸發的方法。為了讓我們的應用程式知道使用者點選了螢幕上的哪一個按鈕,我們需要實作OnClickListener接口并将其綁定到某個按鈕上。這樣,當使用者點選該按鈕時,OnClickListener就會通知我們的應用。
// 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個新的屬性——沖泡時間、沖泡倒計時、已經完成杯數以及倒計時是否正在進行的标記。
protected int brewTime = 3;
protected CountDownTimer brewCountDownTimer;
protected int brewCount = 0;
protected boolean isBrewing = false;
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方法中添加對“沖泡時間”和“成功沖泡杯數”這兩個屬性的初始化操作。
在工程實踐中,推薦将下面這些方法單獨地列寫于各個子產品類中,這裡隻是為了簡單起見才把他們全部寫在BrewClockActivity這一個類中。
// 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");
}
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方法設定顯示的labels。在startBrew方法中,我們建立并啟動了一個以秒為機關的倒數計時器,直到一次沖泡完成。注意,我們内嵌地實作了該倒數計時器的兩個監聽方法(onTick和onFinish)。onTick方法每1000毫秒(1秒)便會被調用一次,直到倒數計時為0時,onFinish方法被調用。
為了使得本教程的代碼更加簡潔,我故意将那些标簽字元串(比如“Brew Up!”,“Start”,“Stop”等)直接寫死在了JAVA代碼裡。當從大一點的工程項目來考慮, 這是非常糟糕的程式設計實踐,因為它将會給查找或修改這些字元串帶來極大的麻煩。
Android提供了一個更簡潔的辦法,通過R類将這些字面文本從你的JAVA寫死中分離出來。
R類允許你在一個xml檔案(res/values/strings.xml)中定義并在JAVA實作代碼中引用整個應用程式所需的字元串資源。
例如:
# /res/values/strings.xml
<string name="brew_up_label">Brew Up!</string>
# /res/com/example/brewclock/BrewClockActivity.java
brewLabel.setText(R.string.brew_up_label);
現在,如果你想将應用程式中的“Brew Up!”這個文本換成别的,你需要做的僅僅是修改這個xml檔案中的值,你的應用程式便會将項目中所有用到這個資源的字元串字面值更新,這真是太棒了!
我們的代碼已經完工,現在是時候體驗一下效果了。點選“運作”或者按快捷鍵“Ctrl+F11”啟動模拟器。當一切啟動就緒,你就會看到我們之前設計的界面了,現在,是時候泡杯咖啡了!試着設定不同的沖泡時間并點選Start按鈕,觀察下倒數計時器吧 ^ ^
<a href="http://blog.51cto.com/attachment/201201/151335750.jpg" target="_blank"></a>
此文為bill初學Android時的教程,感覺講解邏輯清晰,代碼完整,指導意義強,特翻譯過來,希望能讓更多的朋友受益。
最後,bill真心希望有熱心的朋友幫我找找翻譯中的弊病,這樣bill才好和大家一起學習進步!再次感謝。
本文轉自Bill_Hoo 51CTO部落格,原文連結:http://blog.51cto.com/billhoo/766303,如需轉載請自行聯系原作者