天天看點

【Android經典入門教程-下(bill譯)】 【前言】   【譯文-下】 建立你的第一個Android應用 【後記】

本文由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注:最好自己手動寫一遍】

&lt;?xml version="1.0" encoding="utf-8"?&gt; 

&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 

    android:orientation="vertical" android:layout_width="fill_parent" 

    android:layout_height="fill_parent"&gt; 

    &lt;LinearLayout android:orientation="horizontal" 

        android:layout_width="fill_parent" android:layout_height="wrap_content" 

        android:padding="10dip"&gt; 

        &lt;TextView android:layout_width="wrap_content" 

            android:layout_height="wrap_content" android:textSize="20dip" 

            android:text="Brews: " /&gt; 

        &lt;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" /&gt; 

    &lt;/LinearLayout&gt; 

        android:layout_weight="1" android:gravity="center" android:padding="10dip"&gt; 

        &lt;Button android:id="@+id/brew_time_down" android:layout_width="wrap_content" 

            android:layout_height="wrap_content" android:text="-" 

            android:textSize="40dip" /&gt; 

        &lt;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" /&gt; 

        &lt;Button android:id="@+id/brew_time_up" android:layout_width="wrap_content" 

            android:layout_height="wrap_content" android:text="+" 

    &lt;Button android:id="@+id/brew_start" android:layout_width="fill_parent" 

        android:layout_height="wrap_content" android:layout_gravity="bottom" 

        android:text="Start" /&gt; 

&lt;/LinearLayout&gt; 

正如你所見,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 &lt; 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 

 &lt;string name="brew_up_label"&gt;Brew Up!&lt;/string&gt; 

 # /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,如需轉載請自行聯系原作者