My favorites | Sign in
Logo
                
Search
for
Updated Nov 03, 2009 by gasolin
Labels: tw
BmiLogic  
完成 BMI 程式

至此,我們已經完成了 bmi 程式的介面設計,並且理解了了新建立的程式。剩下我們要做的,只剩下為 BMI 程式加上程式邏輯囉。

很幸運的是,BMI 程式中用到的並不是什麼神秘的演算法,你甚至可以透過搜尋引擎找到中文的範例。

完整的程式如下:

1  package com.demo.android.bmi;
2
3  import java.text.DecimalFormat;
4
5  import android.app.Activity;
6  import android.os.Bundle;
7  import android.view.View;
8  import android.view.View.OnClickListener;
9  import android.widget.Button;
10 import android.widget.EditText;
11 import android.widget.TextView;
12
13 public class Bmi extends Activity {
14     /** Called when the activity is first created. */
15     @Override
16     public void onCreate(Bundle savedInstanceState) {
17         super.onCreate(savedInstanceState);
18         setContentView(R.layout.main);
19
20         //Listen for button clicks
21         Button button = (Button)findViewById(R.id.submit);
22         button.setOnClickListener(calcBMI);
23     }
24
25     private OnClickListener calcBMI = new OnClickListener()
26     {
27         public void onClick(View v)
28         {
29             DecimalFormat nf = new DecimalFormat("0.00");
30             EditText fieldheight = (EditText)findViewById(R.id.height);
31             EditText fieldweight = (EditText)findViewById(R.id.weight);
32             double height = Double.parseDouble(fieldheight.getText().toString())/100;
33             double weight = Double.parseDouble(fieldweight.getText().toString());
34             double BMI = weight / (height * height);
35
36             TextView result = (TextView)findViewById(R.id.result);
37             result.setText("Your BMI is "+nf.format(BMI));
38
39             //Give health advice
40             TextView fieldsuggest = (TextView)findViewById(R.id.suggest);
41             if(BMI>25){
42                 fieldsuggest.setText(R.string.advice_heavy);
43             }else if(BMI<20){
44                 fieldsuggest.setText(R.string.advice_light);
45             }else{
46                 fieldsuggest.setText(R.string.advice_average);
47             }
48         }
49     };
50 }

我們會學到:導入其他用到的模組、如何取得介面元件、如何對按鈕設定動作。

從上面的完整程式中,我們看到上面介紹到的程式主體都還在,不過也增加了一些內容。這些內容即我們的主要程式邏輯。

講解

//Listen for button clicks

兩個反斜線是 java 語言所支援的另一種註解方式。

按鈕

Button button = (Button)findViewById(R.id.submit);

宣告一個 button 實體,透過 findViewById 方法,從資源檔中取得對應的介面元件(按鈕)。這邊取出的是「R.id.submit」按鈕元件。

「R.id.submit」對應到 XML 描述檔的資源是

<Button id="@+id/submit"
/>

為了確保宣告的型別跟 XML 描述檔中描述的介面元件型別一致,好使程式運作正常,我們在 「findViewById」 方法前加上 「(Button)」修飾,強制將取得的資源型別設成 「button」型別。

button.setOnClickListener(calcBMI);

這句包含了「Button」類別中的「setOnClickListener」方法。方法中傳入了一個「calcBMI」函式。Android 系統的 UI 互動方式採用常見的事件驅動方式。也就是當使用者按下「button」按鈕的時候,Android 系統會去觸發按鈕的「setOnClickListener」方法中所指定的「calcBMI」函式。

觸發事件函式

    private OnClickListener calcBMI = new OnClickListener() { 
        public void onClick(View v) {
            …
        }
    };

範例中所有的邏輯與運算內容,都放置在這個事件函式中。

當使用者按下按鈕時,即觸發「OnClickListener」類型的事件函式。也有人將這種函式稱為回呼(Call Back)函式,因為是當有動作做完(使用者按下了按鈕),才會呼叫(算出 BMI 值)。

編輯欄位

EditText fieldheight = (EditText)findViewById(R.id.height);
EditText fieldweight = (EditText)findViewById(R.id.weight);

與上面 button 的宣告類似,只是改成宣告 EditText 實體,透過 findViewById 方法,從資源檔中取得對應的文字欄位元件。這邊取出的是「R.id.height」和「R.id.weight」文字欄位元件。

運算

double height = Double.parseDouble(fieldheight.getText().toString())/100;
double weight = Double.parseDouble(fieldweight.getText().toString());
double BMI = weight / (height * height);

BMI 值的算法是「體重除以身高的平方」。 用計算式來表示,就是

體重(weight) / 身高(height)*身高(height)

這麼看來,上面的程式碼就很清晰了。我們先從身高欄位(fieldheight)、體重欄位(fieldweight)中取得使用者輸入的身高體重數字,再定義一個雙倍精度幅點數(double) 型態的變數 BMI 來儲存運算的結果,因此,BMI 變數中儲存了運算出來的實際 BMI 值。

顯示結果

我們把 BMI 值運算出來了,接著要將結果顯示回螢幕上。

TextView result = (TextView)findViewById(R.id.result);

為了將結果顯示到螢幕上,在之前 XML 定義檔中我們已經預留了一個名為「result」的 TextView 欄位。在程式碼中,我們再宣告一個 TextView 實體,透過 findViewById 方法,從資源檔中取得對應的介面元件(文字顯示)。這邊取出的就是「R.id.result」介面元件。

DecimalFormat nf = new DecimalFormat("0.00");
result.setText("Your BMI is "+nf.format(BMI));

透過 java 內建的 DecimalFormat 函式,我們可以將運算結果,以適當的格式顯示。

透過「setText」方法,我們可以將指定的字串,顯示在螢幕上文字類型的介面元件中。

顯示建議

「顯示建議」的方式與「顯示結果」完全相同,只有多加了幾個「if」判斷式:當BMI 值大於25顯示過重,小於20顯示過輕。程式碼留給讀者自習。

//Give health advice
TextView fieldsuggest = (TextView)findViewById(R.id.suggest);
if(BMI>25){
    fieldsuggest.setText(R.string.advice_heavy);
}else if(BMI<20){
    fieldsuggest.setText(R.string.advice_light);
}else{
    fieldsuggest.setText(R.string.advice_average);
}

完整的 BMI 程式動作流程,就是使用者在身高體重欄位中輸入好身高體重後,按下「計算 BMI 值」按鈕,程式根據識別符號,從對應的身高體重欄位讀取輸入的值,並做計算,最後將計算的結果與建議顯示到螢幕上。

< 解讀程式流程 | 回目錄 | 重構程式 >


對於本章,您還期望知道什麼樣的內容呢?請在下方提出建議!


Comment by xiaobrahmos, Jun 12, 2008

GOOD!

Comment by anshan.tju, Sep 18, 2008

quite well

Comment by Brooke.Gu, Feb 24, 2009

I think It is a good tutorial for new learner. thanks for your kindness.

Comment by kwiwon, Feb 26, 2009

thanks for your help. your tutorial is very helpful.

Comment by hohoxl, Mar 05, 2009

怎么没有具体说明OnClickListener?这个内部类的程式码呢?

Comment by nrg19840409, May 16, 2009

很好的新手教程啊 感谢

Comment by pail.jin, May 25, 2009

我模拟器上运行了这个bmi程式后,在输入体重和身高的时候,虚拟键盘自动出来了,方便输入后,点击button计算后,虚拟键盘并不会自动消失。 请问,如何让虚拟键盘消失呢?

Comment by gasolin, May 25, 2009

pail.jin; 按 Menu 鍵吧

Comment by hebingYYDog, Jun 03, 2009

有widget方面的吗?

Comment by gasolin, Jun 03, 2009

hebingYYDog, 這教程看完應該就可以看懂官方文件啦 :)

Comment by coloer, Jul 10, 2009

20 //Listen for button clicks 21 Button button = (Button)findViewById(R.id.submit); 22 button.setOnClickListener(calcBMI); 23 } 24 25 private OnClickListener? calcBMI = new OnClickListener?() 26 { 27 public void onClick(View v) …… 可以先使用calcBMI 后定义吗? 有点不理解

Comment by arthurtw, Aug 04, 2009

這書是好的,但是我照抄居然會錯,我太笨

Comment by WenYuan.Tasy, Aug 07, 2009

雖然已是程式老手,新接觸Android的我還是需要、想要這樣一份清楚詳細的初級教學。 我會繼續逐字研讀,感謝分享。

Comment by how2094, Aug 21, 2009

Android因為有您的無私一定會更加拙壯,鉅細靡遺,感謝!!

Comment by bakalang, Sep 09, 2009

很詳細的教學,感謝你的分享.

Comment by nullme.hsu, Sep 11, 2009

雖然已經會寫Java,工作也跟J2EE息息相關。 您寫的說明超容易入門,我要多學習。

Comment by zhikook, Sep 21, 2009

我在模擬器和真機上測試,在界面輸入身高、體重,提交數據時,程序出錯停止了。請教

Comment by gasolin, Sep 21, 2009

zhikook, 去比較 http://code.google.com/p/androidbmi/source/list 裡的原始碼看看輸入有什麼問題

Comment by new126r...@126.com, Oct 02, 2009

有点不明白OnClickListener?对象的onClick()方法 和按钮的setOnClickListener() 方法是如何配合运行的,按非OOP思维(年初才开始学JAVA,以前只做过Power Builder项目)给按钮对象定义或重载一个onClick()方法就行了,其他的事交给系统处理,系统会自动捕捉点击事件,捕捉到之后会自动调用onClick()方法,PB中还可以按点击的鼠标左、中、右键及左中右键的组合方式的不同来分开执行onClick()方法,例如按住Ctrl键同时按鼠标左键与单独按鼠标左键(或同时按下鼠标左键与右键)就会执行不同代码产生不同效果(如果代码中有不同处理的话)

Android 的 API 文档看着就犯晕,不如JavaFX的API文档写的好,也许是个人阅读习惯的问题

Comment by e...@live.cn, Oct 15, 2009

好棒,一次成功!

Comment by liuzhu145, Dec 02, 2009

为什么我敲入文中的代码,显示 The type new View.OnClickListener?(){} must implement the inherited abstract method View.OnClickListener?.onClick(View)的错误。

Comment by gasolin, Dec 02, 2009

所以要繼續把 onClick(View v) 敲進去....

Comment by liuzhu145, Dec 02, 2009
昨天因为不小心把onClick的o敲成O了,所以报抽象接口中的方法没有实现的错误。后面同学给我给我说了一个Eclipse的快捷键可以避免这中错误。在将光标放在OnClickListener?的大括号中,按alt+shif+s,就会出现必须OnClickListener?必须实现的方法,选择出现的方法,在Eclipse会在大括号中添加此方法,自己在实现这个方法就可以。多谢gasolin的回复

Sign in to add a comment
Hosted by Google Code