使用Intent轉換Activity並傳遞資料,什麼是Intent意圖?

使用Intent轉換Activity

要如何由原本的第一個MainActivity轉換到我們剛產生的ResultActivity呢?答案是使用Intent,也就是「意圖」,Intent代表使用者與應用程式的互動,互動通常會產生變化,例如按下一個圖示後進行撥出電話,或者按下一個按鈕後轉換到另一個畫面(也就是另一個Activity)。使用android.content.Intent類別可以達到這些功能,Intent類別的建構子有很多種,其中常用來轉換Activity的建構子規格如下:

Intent(Context packageContent, Class<?> cls)

這個建構子的第一個參數是Context,代表從那一個Activity出發,如果在MainActivity中產生Intent,那就是代表MainActivity本身,可使用「this」關鍵字,第二個參數則需給予轉換目的地的類別,本例為ResultActivity,應該使用「ResultActivity.class」,範例程式碼如下:

Intent intent = new Intent(this, ResultActivity.class);

上例程式碼產生一個名稱為小寫「intent」的Intent物件,但此時intent並不會有任何作用,它只是個在記憶體中的物件罷了,在一個Activity中可以使用startActivity方法,將一個intent物件發送至Android系統中,由Android系統判別,判別後由系統將我們的ResultActivity顯示在畫面上,範例程式碼如下:

startActivity(intent);

請在MainActivity的bmi方法中實作以上程式碼,在運算並得到bmi值後,產生Intent物件,並呼叫startActivity方法,部份程式碼如下:

    public void bmi(View v){
        EditText edWeight = (EditText) findViewById(R.id.weight);
        EditText edHeight = (EditText) findViewById(R.id.height);
        float weight = Float.parseFloat(edWeight.getText().toString());
        float height = Float.parseFloat(edHeight.getText().toString());
        float bmi = weight/(height*height);
        Intent intent = new Intent(this, ResultActivity.class);
        startActivity(intent);
    }

執行結果,當輸入體重與身高並按下計算按鈕後,會轉換至ResultActivity,如下圖:

目前新的ResultActivity仍然未實作BMI顯示的功能,接下來我們將一一完成必須的程式設計工作。

使用Intent傳遞資料

在MainActivity中所計算得到的bmi值要如何在轉換至ResultActivity時,一併將bmi資料傳遞過去呢?答案是使用Intent,可以在Intent物件中夾帶資料,在轉換後再取出資料後使用,這種在Intent中的資料稱為「Extra」額外附帶的資料。

簡單資料

如果欲傳遞的值很簡單,就像本例的浮點數(float)bmi值,可直接使用Intent類別所提供的putExtra方法,在轉換Activity之前,將資料(本例為bmi)放進去Intent物件中,如:

Intent intent = new Intent(this, ResultActivity.class);
intent.putExtra("BMI_EXTRA", bmi);
startActivity(intent);

程式碼的第二行,在執行startActivity方法之前,將bmi值放進intent物件中,必須在放入時指定一個名稱字串,也就是為這個資料命名一個標籤如「BMI_EXTRA」,未來使用這個標籤就能取得資料了。在本例中,放入資料的程式碼實作在MainActivity中,也就是計算bmi且已產生intent物件後。

而在轉換Activity後的目的地(本例為ResultActivity),可在onCreate方法中,取得在前一個Activity己放入的資料。由於資料是放在Intent中,因此必須先呼叫Activity所提供的方法getIntent()得到Intent物件,如下:

Intent intent = getIntent();

再使用Intent類別的getXXExtra方法取得其中所附帶的資料,如本例之前放入的是float型態的資料,在此就應使用getFloatExtra方法,如下:

float bmi = intent.getFloatExtra("BMI_EXTRA", 0);

這類取得附檔資料的方法的第一個參數為字串,代表資料的標籤,而第二個參數是使用該標籤而取不到資料時的預設值,本例定義為0。如果資料是整數int時,使用getIntExtra方法,是String資料時,就使用getStringExtra方法。Intent類別提供了以下幾個常用取得資料的方法:

方法名稱 說明
getFloatExtra 取得float型態資料
getIntExtra 取得int型態資料
getLongExtra 取得long型態資料
getBooleanExtra 取得boolean型態資料
getCharExtra 取得char型態資料
getStringExtra 取得String型態資料
getStringArrayExtra 取得String陣列型態資料
上述型態也都有取得對應陣列的方法
getStringArrayListExtra 取得內含String的List集合資料
上述型態也都有取得對應集合的方法

顯示在畫面上

取得前一個Activity傳遞過來的資料後,現在可以將資料送到畫面上,請讀者打開ResultActivity的畫面配置檔「res/layout/activity_result.xml」,設計畫面中加入一個TextView元件(Large Text),再設定TextView元件的id,連擊TextView元件,在id欄位中更改為「result」(或點擊元件後,在右邊的屬性視窗),如下圖:

修改後按下Enter鍵即完成設定,回到ResultActivity中的onCreate方法,加入程式碼,先取得畫面中的TextView元件,再將bmi值設定在TextView元件中,如下程式碼:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_result);
    Intent intent = getIntent();
    float bmi = intent.getFloatExtra("BMI_EXTRA", 0);
    TextView result = (TextView) findViewById(R.id.result);
    result.setText("您的BMI值為:"+bmi);
}

執行結果如下圖,在ResultActivity中顯示MainActivity所運算的BMI結果:

複雜的資料-使用Bundle類別

如果有多種類的資料需要傳遞,可使用Bundle類別,Bundle類別類似一個袋子,先將所有要傳遞的資料放在一個袋子中,最後再將袋子放到Intent中,如下:

先產生一個Bundle物件:

Bundle bag = new Bundle();

再使用Bundle類別的putXX方法,放入不同型態的資料:

bag.putFloat("BMI_EXTRA", bmi);
bag.putString("TEST_EXTRA", "Testing");

最後,再呼叫Intent類別的putExtras方法,將bag放入:

intent.putExtras(bag);

而在ResultActivity中的onCreate方法中,需先呼叫getIntent()得到Intent物件後,再呼叫getExtras()方法取得Bundle物件,再取得Bundle中的資料,如下:

float bmi = intent.getExtras().getFloat("BMI_EXTRA", 0);

或是先取得Bundle物件後,再一一取得資料,如下:

Bundle bag = intent.getExtras();
float bmi = bag.getFloat("BMI_EXTRA", 0);
String test = bag.getString("TEST_EXTRA", null);

提示:
使用Bundle確實多了一道手續,而在執行的結果上好像沒什麼差別,其實,Bundle如果在程式未來有需求更動時,會帶來較方便的效果。例如,如果之後決定要在傳遞資料前,先將所有資料儲存在資料庫時,就可將Bundle物件傳遞到其他方法去處理,而不用傳遞多個散亂資料。

Comments

No comments yet. Why don’t you start the discussion?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *