iT邦幫忙

DAY 28
5

Android 學習手札系列 第 28

Day 28 - Android - R命脈

今天要為各位介紹一些比較觀念性的東西,以及介面上的每個元素是如何與程式產生關聯性。

同時在最後會為各位說明Day 26 - Android - 第二個世界元素在最後請各位嘗試的小作業。
在一開始前,希望各位可以看過「Android – 專案的建立與結構」這篇,先大略地了解一下我們 Android 世界的專案結構,畢竟已經寫過了,這邊就不再直接貼過來(誤),以示誠意XD

一個原生的 Android App 在自己撰寫開發時,原則上就是兩天核心,一個原始碼(src),另外一個是資源(res),而在我們撰寫程式碼的過程中,若是各位有注意到的話,只要打上 R.id. 還不用打完,稍微等候一下,或是鍵入「Alt + /」時,會如下圖出現 id 相關的提示碼。

這些都是我們建立在介面上的元素,有 id 的元素,而那些 id 在命名時都是以「@+id/call_me_id」這樣的方式,以「@+id」為開頭,接「/」後再接我們要給予「名稱」為格式,後都名稱的部份跟平常我們寫程式一樣,以英文大小寫字母為開頭,後接任何大小寫的英文或數字皆可,符號也一樣就是只認底線(_)而已,至於格式的部份沒有限定,用底線(_)將每個單字隔開只單純是在下的撰寫習爾。

至於放在前方的「@+id」是 android 特有的格式,他的用意在告訴 sdk 說,我要新增一個 id 了,倘若 at(@) 之後沒有用加號(+)隔開,意指在取得既有的資源,比如說 @string/...,這個部份各位可以親自到開發者文件的 ID 裡,有詳細說明。另外, id 的命名一定不能重覆,而這個條件在平常是沒有什麼問題,但隨著專案越來越龐大的時候,就可能會發生類以像下述狀況:
MoogleActivity 的介面 activity_moogle.xml 裡有一個要擺姓名為「莫古哩」的文字元件(TextView)
ChocoboActivity 的介面 activity_chocobo.xml 裡也有一個姓名的文字元件要放「陸行鳥」
在文字呈現上沒有問題,但是在命名時,也不能都取成「@+id/name」呀!
那就命名為「@id/name1」跟「@id/name2」吧~這樣看似解決了同名的問題~但是,我們回到程式碼來看,

有注意到什麼嗎?今天我們在任何一個八杆子打不著的 activity 裡面這麼輸入時,不管是不是本身介面上的元素,系統都會自動提示出來給我們看XD
這時只有兩個,還能分得清楚,但別忘嘍~正如同上面所說,這時的專案還不大,但是在未來越來越多要被命名為 name 的元素,在一堆 namexxx 的全部出現"提示"時,那還真有種被施了「混亂術」一般的暈呀!若是那天大腦在過熱一下,那就一直在那裡轉圈圈啦XD

所以這邊提供一個在下的命名習慣供各位參考:「元素類型_哪個activity_命名」,以上述的類字來說就是「txt_moogle_name」以及「txt_chocobo_name」這樣就很清楚了,當然這是一個建議方式,各位可以自行使用一個合適的方式來命名之嘍!

在「@+id」的時候,系統~也就是 SDK 會判斷在整個專案沒有問題時,自動幫我們加入到一個堪稱命脈的目錄檔案裡:「gen/R.java」,這個目錄裡的檔案都是 SDK 為我們產生出來的,這時候請各位隨意挑一個專案的 R.java 來看之,

這邊的組成也就是每個資源都被視為一種"物件",裡面放的都是被自動產生出來的"資源"以 id 為例

public static final class id {
    public static final int LinearLayout1=0x7f08000f;
    public static final int btn_back=0x7f080006;
    public static final int btn_back_to_pre=0x7f080019;
    public static final int btn_moogle3_back=0x7f08001a;
    public static final int btn_send=0x7f08000e;

他就是一個被命名為「id」的物件,裡面放了所有我們有使用「@+id」來命名的靜態常數變數,後面十六進位的數字,我們可以視之為每個元素住的房間(記憶體)號碼,當我們在撰寫程式碼或是在編譯時,系統自己會幫我們藉由這些要這些編號找到這個介面上的元素來處理之。而在這裡,我們也能看到,我們目前建立出了哪些資源來,只是平常也不需要來這裡看啦XD

所以今天到這邊各位了解這個構成了嗎?

===========================================================
接下來就為各位說明Day 26 - Android - 第二個世界元素當天的作業嘍~

當天是請各位思考,如何讓 Moogle2 隨機勾選的人員名單(產出的message,忘記的朋友,請自行到Day 25 - Android - 簡介與列表去回複一下記憶XD),當我們回到 Moogleacitivty 時,還能夠被提來,放入傳遞內容的輸入框(EditView)中。

先回想一下,該 message 是被在何時被建立的…

嗯,就是在 Moogle2 按下返回按鈕回到 Chocobo 的那個偵聽式裡,所以我們要在 setResult 之前把 message 字串放進記憶中

...
intent.putExtra("message", message);
//宣告 SharedPreferenece
SharedPreferences preferences = getSharedPreferences("MOSIL", MODE_PRIVATE);
preferences.edit().putString("message", message).commit();

setResult(Number.MOOGLE2, intent);
...

再來我們就可以直接回到 Moogle 去思考一下,要在哪裡執行這個放入 EditText 的動作了,根據前兩天的過程中,可能有人會直覺那就放在返回處理的 onActivityResult 區段之中吧!

不過,這個時候若是有人點下實體的「返回鍵」而非點介面上的「返回按鈕」呢?
也許有人很認真的朋友,會根據Day 9 - Android - 流程與紀錄貓回答說,那我就放在「onRestart」區塊吧!

若您這麼回很聰明,真的要給您一個讚還同時要說您有認真的吸收內化成自己的東西!

可惜,這個時候是不對的XD

因為,在這個時候,我們是使用 startActivityForResult() 跳到 Chocobo 去了,所以在回傳時,其實程式流程是會先往 onActivityResult() 區塊走去。然而這個時候我們還會遭遇到一個問題!

從 Chocobo 回來,傳回碼 "resultCode" 也沒意外的走到了 "case Number.Chocobo" 去了,但是,因為是被按了實體的返回鍵,所以並沒有回傳內容來,這個時候的 data 是空的!所以,這邊要再加上一個判斷:

case Number.Chocobo:
    if(data != null){
        mSpnSignal.setSelection(data.getIntExtra("signal_id", 0));
    }
    break;

確定 data 不為空我們才再做設定的事情。這麼一來,我們就能安心的再繼續進行下去啦,再來我們就能回到原本設想的流程裡,在 onRestart() 裡面加入下面這段程式嘍

@Override
protected void onRestart() {
    super.onRestart();
    SharedPreferences preferences = getSharedPreferences("MOSIL", MODE_PRIVATE);
    //取出暫存在硬體上的 message ,若他沒有值時,就給予 ""(空字串)
    String message = preferences.getString("message", "");
    mEdtMessage.setText(message);
}

如此一來,就完成啦!趕快去執行看看吧

Day 27 - Android - 自我《 Day 29 - Android - Style


上一篇
Day 27 - Android - 自我
下一篇
Day 29 - Android - Style
系列文
Android 學習手札30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

我要留言

立即登入留言