構(gòu)建你的第一個(gè)應(yīng)用(app)
歡迎來到安卓開發(fā)!
這個(gè)課程教你如何構(gòu)建你的第一個(gè)應(yīng)用。你講會(huì)學(xué)到如何去創(chuàng)建一個(gè)安卓工程和啟動(dòng)一個(gè)可以調(diào)試的應(yīng)用的版本。你將會(huì)學(xué)到一些安卓設(shè)計(jì)的基礎(chǔ),包括如何構(gòu)建一個(gè)簡(jiǎn)單的用戶界面和處理用戶輸入。
在你開始這個(gè)課程之前,確保你已經(jīng)有了安卓開發(fā)環(huán)境并設(shè)置好,你需要:
1.下載安卓開發(fā)包(Android SDK)
2.為你的Eclipse安裝ADT插件(如果你使用Eclipse集成開發(fā)環(huán)境的話)
3.使用SDK管理器(SDK manager)下載最新的SDK工具盒平臺(tái)
注意:在你開始本課程之前,確保你安裝了最近版本的ADT插件和安卓SDK。這個(gè)課程的進(jìn)度描述不適用于早期的版本。
如果你還沒有完成這些任務(wù),開始下載 Android SDK 并且跟隨安裝步驟。一旦你已經(jīng)完成了安裝,你就準(zhǔn)備好開始這個(gè)課程了。
這個(gè)課程使用了一種訓(xùn)練格式,就是不斷的構(gòu)建一個(gè)簡(jiǎn)單的app的方式,講會(huì)教會(huì)你一些關(guān)于安卓開發(fā)的基礎(chǔ)概念,跟隨每一個(gè)步驟是很重要的。
開始第一課 Start the first lesson ?
創(chuàng)建一個(gè)安卓項(xiàng)目
一個(gè)安卓項(xiàng)目包含了由源代碼組成的的你的應(yīng)用的全部文件。安卓開發(fā)包SDK工具可以很容易的創(chuàng)建一個(gè)由默認(rèn)項(xiàng)目文件夾和文件組成的新的安卓項(xiàng)目。
這節(jié)課展示了,如何創(chuàng)建一個(gè)新的項(xiàng)目,你可以選擇兩種方式之中的一種:使用帶有ADT插件的Eclipse或者使用SDK工具在命令提示符下。
注意:你應(yīng)該已經(jīng)準(zhǔn)備好了并安裝完成安卓SDK,如果你使用Eclipse,你應(yīng)該已經(jīng)安裝好ADT插件(22.6.2或者更高版本)。如果你還未做好這些,請(qǐng)?jiān)陂_著這節(jié)課的學(xué)習(xí)之前,跟隨指南去安裝安卓開發(fā)工具包 Installing the Android SDK。
使用Eclipse創(chuàng)建項(xiàng)目
1.在工具欄上點(diǎn)擊 New
2.在出現(xiàn)的窗口上,打開 Android 文件夾,選擇 Android Application Project ,并且點(diǎn)擊 Next。
3.填寫出現(xiàn)的表單內(nèi)容:
Application Name 應(yīng)用程序的名稱。是向使用者展示的應(yīng)用程序的名稱。在這個(gè)項(xiàng)目里,使用“My First App”。
Project Name 項(xiàng)目名稱。是你的項(xiàng)目的文件夾的名稱,也是在Eclipse里看到的名稱。
Package Name 程序包名。是你的程序包的命名空間(和Java編程語言的包的概念是相同的規(guī)則)。你的包名必須是在你的安卓系統(tǒng)的所有的包中是唯一的。因此,一般最好的情況是,你使用一個(gè)你的組織或者發(fā)布者實(shí)體的保留域名作為開頭,在這個(gè)項(xiàng)目里,你可以使用像“com.example.myfirstapp”,然而,你不能在谷歌市場(chǎng)(Google Play)發(fā)布你的使用“com.example”命名空間的應(yīng)用。
Minimum Required SDK 最小要求SDK 是你的應(yīng)用支持的最低安卓系統(tǒng)版本。使用API 級(jí)別來指定。為了支持更多可能的設(shè)備,你設(shè)置成你的應(yīng)用可以提供的核心性能集合支持到的最低版本。如果你的應(yīng)用的一些特性可能僅僅在較新的版本上,并且它不是在你的所有應(yīng)用特性中起到?jīng)Q定性作用的話,你可以在它運(yùn)行在它支持的版本上時(shí)才啟用它。(更多的討論請(qǐng)閱讀 支持不同平臺(tái)的版本 Supporting Different Platform Versions). 在本項(xiàng)目中,我們將這些設(shè)置保留為默認(rèn)值.
Target SDK 目標(biāo)SDK 指示了你測(cè)試過的你的應(yīng)用可以支持的最高版本的安卓系統(tǒng)(仍然是用API級(jí)別指定)
當(dāng)一個(gè)新的安卓版本變得可用,你應(yīng)該測(cè)試你的應(yīng)用在新的安卓版本并且更新這個(gè)值去匹配最新的API級(jí)別,這樣你能獲得新平臺(tái)特性的最大效益。
Compile With 編譯版本 是你講編譯你的應(yīng)用程序而使用的平臺(tái)版本。 默認(rèn)情況下,這將被設(shè)置為你手中的可用SDK版本中的最新版本(它可能是安卓4.1或者更高;如果你還沒有任何一個(gè)可用版本,你必須使用SDK Manager安裝一個(gè))。你仍然可以構(gòu)建你的應(yīng)用去支持較舊的版本,但是設(shè)置編譯目標(biāo)為最新的版本將使得你可以啟用新的特性和優(yōu)化你的應(yīng)用程序來獲得在最新設(shè)備上的更好的用戶體驗(yàn)。
Theme 主題 指示了你的應(yīng)用的界面風(fēng)格。你可以讓它保持原樣。
點(diǎn)擊 Next 進(jìn)入下一步。
4.在接下來屏幕上去配置這個(gè)項(xiàng)目,保留默認(rèn)選項(xiàng)并點(diǎn)擊 Next 下一步。
5.在接下來的屏幕可以幫助你創(chuàng)建一個(gè)啟動(dòng)圖標(biāo)。
你可以使用多種方式自定義一個(gè)圖標(biāo),和使用工具創(chuàng)建一個(gè)適合多種屏幕密度的圖標(biāo)。在你發(fā)布你的應(yīng)用之前,你應(yīng)該確定你的圖標(biāo)符合在 圖標(biāo)設(shè)計(jì)指南 Iconography 聲明中的規(guī)范。
點(diǎn)擊Next 下一步。
6.現(xiàn)在你可以選擇一個(gè)Activity(頁面)模板來開始構(gòu)建你的應(yīng)用。對(duì)于這個(gè)項(xiàng)目,選擇 BlankActivity 空模板 和點(diǎn)擊 Next 下一步。
- 保留Activity所有的詳細(xì)設(shè)置為默認(rèn)狀態(tài),并點(diǎn)擊 Finish 完成。
你的項(xiàng)目現(xiàn)在只是一個(gè)基礎(chǔ)的“Hello World”應(yīng)用,它包含一些默認(rèn)文件。要啟動(dòng)這個(gè)應(yīng)用,繼續(xù)學(xué)習(xí)下一節(jié)課next lesson.。
你的項(xiàng)目現(xiàn)在只是一個(gè)基礎(chǔ)的“Hello World”應(yīng)用,它包含一些默認(rèn)文件。要啟動(dòng)這個(gè)應(yīng)用,繼續(xù)學(xué)習(xí)下一節(jié)課next lesson.。
使用命令提示行工具創(chuàng)建項(xiàng)目
如果你沒有使用一個(gè)帶有ADT插件的Eclipse集成開發(fā)環(huán)境,你可以 使用SDK工具從一個(gè)命令提示行工具創(chuàng)建你的項(xiàng)目 來替代它。
1.改變你的文件夾到安卓SDK的安裝目錄 tools/ 下。
2.執(zhí)行
android list targets
這將打印出你的SDK中你已經(jīng)下載的所有可用的安卓平臺(tái)列表。找到你想用來編譯你的APP的平臺(tái)。記錄下目標(biāo)id。我們建議你選用最高級(jí)別的可用版本。你仍然可以構(gòu)建你的APP支持更舊的版本,但是設(shè)置編譯目標(biāo)(build target)為最新的版本允許你在最新的設(shè)備上優(yōu)化你的app。
如果你沒有看到任何內(nèi)容被列出,你需要使用安卓SDK manager去安裝一些。請(qǐng)看 Adding Platforms and Packages.
3.執(zhí)行
android create project --target <target-id> --name MyFirstApp \
--path <path-to-workspace>/MyFirstApp --activity MainActivity \
--package com.example.myfirstapp
使用列出的目標(biāo)(上一步獲得的)替換<target-id>,并且使用你想要保存你的項(xiàng)目的文件夾位置替換<path-to-workspace>。
提示:請(qǐng)?zhí)砑? platform-tools/ 和 tools/ 墓道你的PATH 環(huán)境變量。
NEXT: RUNNING YOUR APPLICATION 下一課:?jiǎn)?dòng)你的應(yīng)用程序
啟動(dòng)你的應(yīng)用
如果你跟隨上一課的內(nèi)容創(chuàng)建了一個(gè)安卓項(xiàng)目,它包含了一些像“Hello World”這樣的默認(rèn)文件,允許你直接啟動(dòng)這個(gè)應(yīng)用。
如何啟動(dòng)你的應(yīng)用依賴這兩項(xiàng):你是否擁有一個(gè)真實(shí)的安卓動(dòng)力的設(shè)備,和你是否使用Eclipse。這節(jié)課將將向你展示如何在真實(shí)設(shè)備和模擬器中安裝和啟動(dòng)你的應(yīng)用,有兩種方式:使用Eclipse或者命令提示符工具。
在啟動(dòng)你的應(yīng)用之前,你應(yīng)該了解一些你的安卓項(xiàng)目里的文件和文件夾:
AndroidManifest.xml
清單文件,描述了應(yīng)用的基礎(chǔ)特性 ,和定義每一個(gè)最近。隨著你閱讀更多的訓(xùn)練章節(jié),你將會(huì)學(xué)到很多的在這個(gè)文件里的聲明(譯者注:定義組件等)
在你的清單文件中應(yīng)該包含的一個(gè)重要的元素是 <uses-sdk> ,它使用 android:minSdkVersion 和 android:targetSdkVersion 聲明了你的應(yīng)用的兼容性。在你的第一個(gè)應(yīng)用中,它看起來是這樣的:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
...
</manifest>
你應(yīng)該總是設(shè)置 android:targetSdkVersion 為盡量高的版本,并且在相應(yīng)的平臺(tái)版本測(cè)試你的應(yīng)用。更多的信息請(qǐng)閱讀 Supporting Different Platform Versions.
src/
你的應(yīng)用程序的主要源代碼文件存放在這里,默認(rèn)情況下,包含了一個(gè)Activity的類,在通過點(diǎn)擊圖標(biāo)后你的應(yīng)用啟動(dòng)時(shí)它將被啟動(dòng)。
res/
包含許多子文件夾用于存放應(yīng)用的資源文件,下面列出了一些:
drawable-hdpi/
一個(gè)文件夾,用于存放一些 被設(shè)計(jì)用于高密度(hdpi)的屏幕的可繪制的對(duì)象(比如位圖)。其他的drawable文件夾也包含了一些 適用于其他屏幕密度而設(shè)計(jì)的資源材料。
layout/
一個(gè)文件夾,用于存放 定義你的應(yīng)用程序的界面 的文件。(譯者注:我們常常成為頁面布局文件)
values/
一個(gè)存放了許多xml 文件的文件夾,包含了很多資源文件,比如 字符串(string) 和顏色(color)定義。
當(dāng)你構(gòu)建并運(yùn)行這個(gè)默認(rèn)的應(yīng)用,一個(gè)默認(rèn)的Activity類將啟動(dòng),和加載一個(gè)包含了“hello world”的布局文件。這個(gè)結(jié)果一點(diǎn)也不讓人興奮,但是重要的是 你明白了如何在開始開發(fā)之前去啟動(dòng)一個(gè)應(yīng)用。
在真實(shí)設(shè)備上運(yùn)行
如果你擁有一個(gè)安卓動(dòng)力的設(shè)備,在這里展示了你如何安裝和啟動(dòng)你的應(yīng)用:
1.使用USB線將你的設(shè)備插入到你的開發(fā)機(jī)器(譯者注:可能是電腦)上,如果你使用window是開發(fā),你可能需要為你的設(shè)備安裝適當(dāng)?shù)腢SB驅(qū)動(dòng)。獲得安裝驅(qū)動(dòng)的幫助請(qǐng)閱讀文檔 OEM USB Drivers 。
2.在你的設(shè)備上啟用USB debugging(USB調(diào)試)模式
在很多運(yùn)行在安卓3.2或者更舊的版本上的設(shè)備,你可以在選項(xiàng)設(shè)置里找到: 設(shè)置>應(yīng)用程序>開發(fā)者
在安卓4.0或者更新一些的版本,他存在于 設(shè)置>開發(fā)者選項(xiàng)
注意:在安卓4.0或者更新一些的版本 開發(fā)者選擇 默認(rèn)是隱藏的。要想使它可見, 在 設(shè)置>關(guān)于設(shè)備 下,并且點(diǎn)擊 基帶版本 多次。返回上一屏幕去尋找 開發(fā)者選項(xiàng)
在Eclipse中啟動(dòng)應(yīng)用:
注意:我們常常使用Eclipse的英文版本,對(duì)于Eclipse里的一些英文都不在翻譯,以應(yīng)對(duì)讀者找不到按鈕的情形。
1.打開一個(gè)你項(xiàng)目中的文件,并且點(diǎn)擊工具欄中的 Run。
2.在出現(xiàn)的 Run as 窗口 里,選擇 Android Application 并且 點(diǎn)擊 OK。
Eclipse 安裝你的應(yīng)用到手機(jī)里并且啟動(dòng)它。
或者在命令提示行里啟動(dòng)它
1.更改文件夾路徑到 你的安卓項(xiàng)目的根目錄 下,并且執(zhí)行:
ant debug
- 確保安卓SDK 的platform-tools/ 文件夾被包含在你的環(huán)境變量PATH里,這時(shí)執(zhí)行:
adb install bin/MyFirstApp-debug.apk
- 在你的設(shè)備上,定位到 MyFirstActivity 并且打開它。
這些就是如何構(gòu)建和在一個(gè)真實(shí)設(shè)備上啟動(dòng)你的應(yīng)用。要開始開發(fā),繼續(xù)到下一課程 next lesson。
在模擬器中啟動(dòng)
無論你使用Eclipse 或者命令提示行,要啟動(dòng)你的應(yīng)用,你必須先創(chuàng)建一個(gè)Android Virtual Device (AVD),一個(gè)AVD是一個(gè)配置好的安卓模擬器,它運(yùn)行你模擬不同的設(shè)備。
創(chuàng)建一個(gè)AVD:
1.啟動(dòng)安卓模擬設(shè)備管理器(Android Virtual Device Manager):
a. 在Eclipse,點(diǎn)擊工具欄中的Android Virtual Device Manager
b. 在命令提示行里,更改目錄到 <sdk>/tools/ 并且執(zhí)行
android avd
- 在Android Virtual Device Manager 面板里,點(diǎn)擊 New。
3.填寫AVD的詳細(xì)信息,設(shè)置name名稱,平臺(tái)目標(biāo)platform target,一個(gè)存儲(chǔ)卡大小SD card size,一個(gè)皮膚skin(默認(rèn)HVGA).
4.點(diǎn)擊 Create AVD
5.從 Android Virtual Device Manager 中選擇一個(gè)AVD,并且點(diǎn)擊 Start 開始。
6.在模擬器啟動(dòng)后,解鎖模擬器屏幕。
在Eclipse中啟動(dòng)這個(gè)應(yīng)用
1.打開一個(gè)你項(xiàng)目中的文件,并且點(diǎn)擊工具欄中的 Run。
2.在出現(xiàn)的 Run as 窗口 里,選擇 Android Application 并且 點(diǎn)擊 OK。
Eclipse安裝這個(gè)應(yīng)用到你的AVD,并啟動(dòng)它。
或者再命令提示行下啟動(dòng)它:
1.更改文件夾路徑到 你的安卓項(xiàng)目的根目錄 下,并且執(zhí)行:
ant debug
2.確保安卓SDK 的platform-tools/ 文件夾被包含在你的環(huán)境變量PATH里,這時(shí)執(zhí)行:
adb install bin/MyFirstApp-debug.apk
3.在你的設(shè)備上,定位到 MyFirstActivity 并且打開它。
這些就是如何構(gòu)建和在模擬器中啟動(dòng)你的應(yīng)用。要開始開發(fā),繼續(xù)下一課程 next lesson。
構(gòu)建一個(gè)簡(jiǎn)單的用戶界面
2014-10-28 張?jiān)骑wVIR 翻譯自: https://developer.android.com/training/basics/firstapp/building-ui.html#Button
安卓的圖形用戶接口(界面)是通過使用一個(gè)由視圖(view)和視圖集合(ViewGroup)對(duì)象組成的層級(jí)結(jié)構(gòu)來構(gòu)建的。View對(duì)象是一些常見UI組件,比如按鈕,文本框,ViewGroup對(duì)象是一些不可見的視圖容器,它定義了子視圖如何擺放,比如在一個(gè)表格里或者一個(gè)垂直列表。
安卓提供了一個(gè)XML詞匯表,它于view和ViewGroup的子類是一致的,這樣你可以在XML中使用界面元素的層級(jí)來定義你的界面。
圖一. 說明了 在布局中,ViewGroup對(duì)象形式如何分支,和包含其他的視圖對(duì)象。
在這節(jié)課,你將創(chuàng)建一個(gè)XML布局,它包含了一個(gè)文本區(qū)和一個(gè)按鈕。在后面的課程中,在按鈕被按下后你將作出反應(yīng),并發(fā)送文本區(qū)的內(nèi)容到其他activity。
創(chuàng)建一個(gè)線性布局(Linear Layout)
在你的項(xiàng)目文件夾 res/layout/下,打開 fragment_main.xml
注意:在Eclipse,當(dāng)你打開一個(gè)布局文件,你將先被展示一個(gè)視圖布局的編輯器。這是一個(gè)編輯器,可以幫你以所見即所得的工具構(gòu)建布局。在這節(jié)課,你將使用XML直接工作,這樣,點(diǎn)擊屏幕下方的fragment_main.xml 標(biāo)簽卡來打開一個(gè)XML編輯器。
當(dāng)你創(chuàng)建這個(gè)項(xiàng)目是你選擇了 BlankActivity (空的activity)這個(gè)模板,它包含了 fragment_main.xml 這個(gè)文件,RelativeLayout 是它的根視圖,并且包含了一個(gè)TextView子視圖。
第一步,刪除 <TextView> 元素,并且更改 <RelativeLayout> 元素為 <LinearLayout>。這是,添加android:orientation 這個(gè)屬性,并且設(shè)置值為“horizontal”。這個(gè)結(jié)果像下面這樣:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
</LinearLayout>
LinearLayout 是一個(gè)View group(一個(gè)ViewGroup的子類),它以垂直或者水平方向兩種之一的方式擺放它的子視圖,使用 android:orientation 屬性來指定方向。每一個(gè) LinearLayout 的子視圖出現(xiàn)在屏幕中的順序和它出現(xiàn)在XML中的順序一致。
另外的兩個(gè)屬性, android:layout_width 和 android:layout_height,對(duì)所有的視圖來說都是必須的,為了指示它們的尺寸。
因?yàn)?LinearLayout 是布局的根視圖,在它的寬度和高度都設(shè)置為“match_parent”,它將填滿這個(gè)應(yīng)用的整個(gè)可用的屏幕區(qū)域。這個(gè)值定義了視圖如何展開它們的寬度和高度去匹配它們的父控件的寬度和高度。
關(guān)于布局屬性的更多內(nèi)容,請(qǐng)閱讀 Layout 指南。
添加一個(gè)文本框
為了創(chuàng)建一個(gè)用戶可編輯的文本區(qū),在 <LinearLayout>.下添加一個(gè) <EditText>元素。
像每個(gè)視圖View一樣,你必須定義固定的XML屬性去指定EditText對(duì)象的屬性。下面演示了 你如何在<LinearLayout> 元素內(nèi)定義它:
EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
關(guān)于這些屬性:
android:id
它提供了這個(gè)視圖的唯一標(biāo)示符,通過它你可以再你的代碼里引用該對(duì)象,比如去讀取和操作這個(gè)對(duì)象(你將會(huì)在下一章節(jié)看到)
當(dāng)你從XML中應(yīng)用資源對(duì)象時(shí),符號(hào)“@”是必須的。隨后跟隨著資源類型(在這里是id類型),一個(gè)斜線,這時(shí)再跟著一個(gè)資源名稱(這里是叫edit_message)
在資源類型前面的“加號(hào)”,僅僅在你第一次定義資源ID的時(shí)候是必須的。在你編譯你的程序時(shí),SDK工具在你的項(xiàng)目的gen/R.java文件中使用ID的名稱去創(chuàng)建一個(gè)資源ID,它引用到EditText元素。一旦你的資源ID使用這種方式聲明過,其他應(yīng)用到這個(gè)ID就不再需要“加號(hào)”了。只有當(dāng)指定一個(gè)新的資源ID時(shí),才需要使用“加號(hào)”,并且不需要具體的資源,比如字符串和布局。更多關(guān)于資源對(duì)象的內(nèi)容請(qǐng)看側(cè)邊條。
android:layout_width 和android:layout_height
為了代替使用具體的尺寸來指定寬度和高度,“wrap_content”值指示了視圖將會(huì)僅僅需要去適應(yīng)視圖的內(nèi)容的大小。如果你使用"match_parent"來代替,這時(shí) EditText元素將會(huì)填充滿整個(gè)屏幕,因?yàn)樗鼘?huì)匹配它的父布局LinearLayout的尺寸。更多信息請(qǐng)閱讀 Layouts 指南。
android:hint
當(dāng)文本區(qū)是空得時(shí)候,這個(gè)磨人的字符串將會(huì)被顯示。代替使用 “硬編碼”(hard-coded)一個(gè)字符串作為值, "@string/edit_message" 這個(gè)值引用到一個(gè)在另外的文件中被定義的字符串資源。因?yàn)檫@個(gè)引用到一個(gè)具體的資源(而不是一個(gè)標(biāo)示符),它不需要使用“加號(hào)”。然而,因?yàn)槟氵^去還未定義一個(gè)字符串資源,你將會(huì)首先看到一個(gè)編譯錯(cuò)誤。在下一章節(jié)通過定義字符串的方式你將會(huì)修復(fù)這個(gè)錯(cuò)誤。
注意:字符串資源具有和元素ID相同的名稱edit_message。然而,引用到資源總是通過資源類型的方式(比如id或者string)具有周期的看,于是,使用相同的名稱不會(huì)導(dǎo)致沖突。
關(guān)于資源對(duì)象(resource objects)
一個(gè)資源對(duì)象簡(jiǎn)單來說就是一個(gè)唯一的整數(shù)名稱,它關(guān)聯(lián)到一個(gè)應(yīng)用程序的資源,比如一個(gè)位圖,布局文件,或者字符串。
每一個(gè)資源都有一個(gè)對(duì)應(yīng)的在你項(xiàng)目里gen/R.java里聲明的 資源對(duì)象。你可以使用在 R 類里的對(duì)象名稱去引用你的資源,比如當(dāng)你為android:hint 屬性指定一個(gè)字符串的值時(shí)。你也可以創(chuàng)建任意的資源ID,并通過android:id來關(guān)聯(lián)到一個(gè)視圖控件,它使得你可以從其他代碼里應(yīng)用這個(gè)視圖控件。
每次你編譯你的應(yīng)用,SDK工具都會(huì)生產(chǎn)R.java文件,你不能手動(dòng)修改這個(gè)文件。更多信息請(qǐng)參閱 Providing Resources.
添加字符串資源
當(dāng)你需要添加文本到用戶界面時(shí),你應(yīng)該總是以資源的方式指定每一個(gè)字符串。字符串資源使得你可以在一個(gè)位置里管理你所有的界面文本,這使得很容易找到和更新字符串文本。外部化(譯者注:把...放到外部)的字符串通過為每一個(gè)字符串資源提供可供選擇的定義的方式,使得你可以根據(jù)不同的語言來本地化你的應(yīng)用。
譯者注:將所有的字符串資源放到單獨(dú)的資源文件中,可以在不同的語言情況下切換不同的資源文件來實(shí)現(xiàn)國(guó)際化。
默認(rèn)情況下,你的安卓項(xiàng)目包含了一個(gè)默認(rèn)的字符串資源文件,它存放在 res/values/strings.xml. 添加一個(gè)字符串并且命名為“edit_message”,并且在“Enter a message.”位置上設(shè)置它的值。(你可以刪除"hello_world"字符串)
當(dāng)你在這個(gè)文件里時(shí),同時(shí)為不久后可以要添加的按鈕添加一個(gè)叫做“Send”的字符串,命名為"button_send".
string.xml的結(jié)果像下面這樣:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My First App</string>
<string name="edit_message">Enter a message</string>
<string name="button_send">Send</string>
<string name="action_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
</resources>
添加一個(gè)按鈕
現(xiàn)在添加<Button>元素到你的布局文件里,它直接跟隨在 <EditText>元素之后:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />
寬度和高度都被設(shè)置為"wrap_content",這樣,按鈕就會(huì)按照需要適應(yīng)按鈕的文本的大小。這個(gè)按鈕不需要android:id屬性,因?yàn)椴恍枰赼ctivity代碼里引用。
讓輸入框填滿屏幕寬度
這個(gè)布局是最近的設(shè)計(jì),這樣包括EditText和Button兩個(gè)小組件僅僅按需要去適應(yīng)他們的內(nèi)容的大小,像圖表2展示的這樣:
圖表2.EditText和Button小組件的寬度被設(shè)置為"wrap_content".
這個(gè)樣子對(duì)于這個(gè)按鈕還很好,但是對(duì)文本框就不那么好了,因?yàn)橛脩舯究梢暂斎胍恍└L(zhǎng)一些的內(nèi)容。那么比較好的情形是實(shí)用文本框填充滿未使用的屏幕寬度。你可以再LinearLayout中使用 重要性 屬性來做,這樣你可以通過android:layout_weight 屬性來指定。
weight的值是一個(gè)數(shù)字,它指示了每個(gè)視圖可以占用的剩余空間的數(shù)量,相對(duì)的是兄弟視圖占用的數(shù)量。這樣的工作有點(diǎn)類似飲料配方里的成分?jǐn)?shù)量:“2份的伏特加,1份的咖啡利口酒”,意思是 三分之二 的飲料是伏特加。比如,如果你讓一個(gè)視圖的weight是2而另一個(gè)是1,總數(shù)量是3,那么第一個(gè)視圖填滿2/3的剩余空間,而第二個(gè)視圖填滿僅剩余的部分。如果你添加了第三個(gè)視圖并設(shè)置weight為1,這時(shí),第一個(gè)視圖(weight等于2)此事將獲得1/2的剩余空間,同時(shí)剩下的兩個(gè)各占1/4。
對(duì)所有的視圖來說,默認(rèn)的weight是0,那么,如果你為僅有的一個(gè)視圖指定任何weight大于0的值,那么這個(gè)視圖填滿無論多少的剩余空間,知道所有的視圖被分配他們需要的空間。這樣,為了在你的布局里使EditText元素填滿剩余的空間,給他一個(gè)weight等于1的值并且,讓不為按鈕設(shè)置任何weight。
<EditText
android:layout_weight="1"
... />
為了去改善布局的性能,當(dāng)你指定了weight屬性,你應(yīng)該更高EditText的寬度為0(0dp)。設(shè)置寬度為0增進(jìn)了布局的性能,因?yàn)槭褂?wrap_content"作為寬度需要系統(tǒng)計(jì)算得出一個(gè)基本上不相關(guān)的結(jié)果,因?yàn)閣eight值需要其他的寬度計(jì)算以填滿整個(gè)剩余的空間。
<EditText
android:layout_weight="1"
android:layout_width="0dp"
... />
圖表3 展示了當(dāng)你為EditText元素分配所有的weight后的結(jié)果。
圖表3. EditText組件被設(shè)置了layout weight,這樣填滿 LinearLayout.的剩余的空間。
下面是你完成后的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText android:id="@+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />
</LinearLayout>
這個(gè)布局被應(yīng)用在一個(gè)默認(rèn)的Activity類中,這個(gè)類是當(dāng)你創(chuàng)建項(xiàng)目時(shí)由SDK工具自動(dòng)生成的,這樣你現(xiàn)在可以啟動(dòng)這個(gè)應(yīng)用看下結(jié)果:
在Eclipse,在工具欄里點(diǎn)擊 Run 。
或者再命令提示行下,更改目錄到你的項(xiàng)目的根目錄,并執(zhí)行:
ant debug
adb install bin/MyFirstApp-debug.apk
繼續(xù)下一課程去學(xué)習(xí) 如何響應(yīng)按鈕的點(diǎn)擊,從文本框讀取內(nèi)容,啟動(dòng)另一個(gè)activity,和更多。
張?jiān)骑wVIR 于 2014-10-28 翻譯自:https://developer.android.com/training/basics/firstapp/starting-activity.html#DisplayMessage
啟動(dòng)其他Activity
在完成了上節(jié)課后,你已經(jīng)有了一個(gè)應(yīng)用,它展示一個(gè)具有文本框和按鈕的 activity(一個(gè)單頁面).在這節(jié)課,你將添加一些代碼到MainActivity,當(dāng)用戶點(diǎn)擊了 發(fā)送Send 按鈕將會(huì)啟動(dòng)一個(gè)新的Activity
響應(yīng)Send按鈕
要響應(yīng)按鈕的點(diǎn)擊事件,打開fragment_main.xml 布局文件,并且添加 android:onClick 屬性到<Button>元素:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
android:onClick="sendMessage" />
這個(gè) android:onClick 屬性的值是"sendMessage",這是你的Activity中的一個(gè)方法(method)的名稱。當(dāng)用戶點(diǎn)擊按鈕時(shí),系統(tǒng)將會(huì)調(diào)用它。
打開MainActivity 類(定位到項(xiàng)目的 src/ 目錄下)并且添加相應(yīng)的方法:
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
// Do something in response to button
}
為了讓系統(tǒng)匹配到這個(gè)方法,方法的名稱必須在 android:onClick中被指定為這個(gè)方法名稱,方法的簽名必須準(zhǔn)確的像展示的一樣。明確的,方法必須符合:
公開的。public
具有一個(gè)void返回值
具有一個(gè) View作為參數(shù),并且僅僅只有一個(gè)闡述(這將是那個(gè)被點(diǎn)擊的view)
下一步,你將填充這個(gè)方法,讀取文本框的內(nèi)容并傳遞文本到另一個(gè)activity.
構(gòu)建以個(gè)intent
一個(gè)Intent是一個(gè)對(duì)象,用以在兩個(gè)分離的組件之間(比如兩個(gè) activity)提供運(yùn)行時(shí)綁定。Intent呈現(xiàn)了一個(gè)應(yīng)用 “想去做某事”。你可以使用intent處理多種多樣的任務(wù),但是大多的時(shí)候,它們常常用來啟動(dòng)其他的 Activity
在endMessage()方法內(nèi),創(chuàng)建一個(gè)Intent去啟動(dòng)一個(gè)叫做“DisplayMessageActivity:”的Activity:
Intent intent = new Intent(this, DisplayMessageActivity.class);
這需要你導(dǎo)入(import) Intent這個(gè)class
import android.content.Intent;
提示:在Eclipse,點(diǎn)擊Ctrl + Shift + O 來導(dǎo)入丟失的類(在Mac下是Cmd + Shift + O)
這里使用的構(gòu)造方法具有兩個(gè)參數(shù):
一個(gè)Context 上下文,是第一個(gè)參數(shù)(這是可用的,因?yàn)锳ctivity類是Context的子類)
應(yīng)用程序組件的類,系統(tǒng)將傳送這個(gè)Intent(在這個(gè)情況下,Activity將會(huì)啟動(dòng))
注意:引用 DisplayMessageActivity 將會(huì)產(chǎn)生一個(gè)錯(cuò)誤,如果你使用一個(gè)IDE,比如Eclipse,因?yàn)檫@個(gè)類目前還不存在。現(xiàn)在先忽略錯(cuò)誤,等下再創(chuàng)建它。
一個(gè)Intent不僅僅允許你去啟動(dòng)其他的activity,而且它還能攜帶一個(gè)包裹(bundle)的數(shù)據(jù)到activity。在sendMessage() 方法內(nèi)部,使用 findViewById() 去獲得 EditText 元素,并且添加它的文本的值到intent里。
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
注意: 你現(xiàn)在需要去導(dǎo)入android.widget.EditText的聲明。一會(huì)再定義EXTRA_MESSAGE 常量。
一個(gè)Intent能夠攜帶一個(gè)集合的以鍵值對(duì)的形式的多種數(shù)據(jù)類型,被稱為 附加(擴(kuò)展)數(shù)據(jù)。putExtra() 方法具有一個(gè) 鍵(key) 的名稱作為第一個(gè)參數(shù),和 值(value) 作為第二個(gè)參數(shù)。
為了在下一個(gè) activity去查詢這個(gè)擴(kuò)展數(shù)據(jù),你應(yīng)該使用常量為intent的這個(gè)擴(kuò)展數(shù)據(jù)定義一個(gè)key。這樣添加 EXTRA_MESSAGE 定義到 MainActivity 的頂部:
public class MainActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
...
}
使用你的應(yīng)用的package name 作為前綴 來為intent的額外數(shù)據(jù) 去定義key,是個(gè)好的應(yīng)用實(shí)踐。這確保它們?cè)诤推渌麘?yīng)用交互時(shí)是唯一的。
啟動(dòng)第二個(gè)Activity
要啟動(dòng)一個(gè)Activity,調(diào)用 startActivity() 并且把你的intent傳遞給它。系統(tǒng)收到這個(gè)調(diào)用并且啟動(dòng)一個(gè)這個(gè)Intent指定的Activity的的實(shí)例。
使用下面的代碼,那個(gè)被Send按鈕調(diào)用的 完整的 sendMessage() 方法 看起來是這樣:
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
為了讓這可以工作,現(xiàn)在你需要去創(chuàng)建 DisplayMessageActivity 類。
發(fā)送一個(gè)intent到其他的應(yīng)用
在這節(jié)課里創(chuàng)建的intent是經(jīng)過考慮的明確的intent,因?yàn)镮ntent指定了準(zhǔn)確的應(yīng)用組件,是intent可以被給與的組件。然而,intent可以是隱性的,在一些情況下,Intent不指定 渴望得到的組件,但是允許一些已經(jīng)在設(shè)備中被安裝的應(yīng)用程序去響應(yīng)這個(gè)intent,以 為了那個(gè)被指定多樣的Intent參數(shù)的action 足夠滿意元數(shù)據(jù)規(guī)范的形式。更多信息請(qǐng)閱讀Interacting with Other Apps 。
創(chuàng)建第二個(gè)Activity
使用Eclipse創(chuàng)建新的Activity
1.在工具欄點(diǎn)擊 New 按鈕
2.在出現(xiàn)的窗口里,打開Android 文件夾并選擇 Android Activity,點(diǎn)擊 Next
3.選擇 BlankActivity ,點(diǎn)擊Next
4.填充activity的詳細(xì)內(nèi)容:
Project: MyFirstApp
Activity Name: DisplayMessageActivity
Layout Name: activity_display_message
Fragment Layout Name: fragment_display_message
Title: My Message
Hierarchial Parent: com.example.myfirstapp.MainActivity
Navigation Type: None
點(diǎn)擊 Finish.
如果你使用一個(gè)不同的集成開發(fā)環(huán)境或者再命令提示行工具,在項(xiàng)目 src/ 目錄下創(chuàng)建一個(gè)叫做DisplayMessageActivity.java 的文件,在 原來的MainActivity.java 文件后面。
打開 DisplayMessageActivity.java 文件。如果你使用Eclipse創(chuàng)建這個(gè)activity:
這個(gè)類已經(jīng)包含了一個(gè)必須的方法 onCreate() 的具體實(shí)現(xiàn)。你將稍后修改這個(gè)方法的實(shí)現(xiàn)。
還有一個(gè)方法onCreateOptionsMenu() 的實(shí)現(xiàn),但是你不需要它,可以刪掉它。
還有個(gè)方法onOptionsItemSelected()的實(shí)現(xiàn),它為action bar 的 up 動(dòng)作處理行為。保持它的樣子。
這里還有個(gè) PlaceholderFragment 類,它繼承自Fragment.你在這個(gè)actiivity的最終版本中不需要這個(gè)類。
Fragment在一個(gè)可重用的模型里分解了應(yīng)用程序的基礎(chǔ)和界面(UI)。更多信息請(qǐng)閱讀: Fragments API Guide 在這個(gè)activity的最終版本里不需要使用fragment。
注意: 如果你沒有使用最后版本的ADT插件,你的activity可能看起來有點(diǎn)不同。確保你安裝最后版本的ADT 插件 來完成這個(gè)練習(xí)。
DisplayMessageActivity 類 看起來像下面這樣:
public class DisplayMessageActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() { }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_display_message,
container, false);
return rootView;
}
}
}
如果你使用了一個(gè)其他的不是Eclipse的IDE,使用上面的代碼更新你的 DisplayMessageActivity 的代碼。
所有的 Activity 的子類必須實(shí)現(xiàn) onCreate() 方法。當(dāng)創(chuàng)建一個(gè)新的activity的實(shí)例時(shí)系統(tǒng)將會(huì)調(diào)用它。這個(gè)方法是 你必須使用setContentView()方法定義activity布局的地方,也是 你處理初始化設(shè)置那些activity組件的地方。
注意: 如果你使用了一個(gè)其他的不是Eclipse的IDE,你的項(xiàng)目沒有包含 在setContentView()中請(qǐng)求的 activity_display_message 布局。這是正常的,你將會(huì)在后面修改這個(gè)方法并且不使用這個(gè)布局。
添加標(biāo)題字符串
如果你使用Eclipse,你可以跳過到下一章節(jié),因?yàn)槟0鍨樾碌腶ctivity提供了標(biāo)題字符串。如果你使用了一個(gè)其他的不是Eclipse的IDE,在strings.xml中添加新activity的標(biāo)題。
<resources>
...
<string name="title_activity_display_message">My Message</string>
</resources>
在清單(manifest)文件中添加
所有的activity都必須在清單文件中聲明,AndroidManifest.xml,使用<activity>元素。
當(dāng)你使用Eclipse工具創(chuàng)建一個(gè)activity,它創(chuàng)建了一個(gè)空的。如果你使用了不同的IDE,你需要自行添加清單文件的入口,像下面這樣:
<application ... >
...
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="@string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
</application>
android:parentActivityName 屬性 聲明了 在應(yīng)用程序的邏輯層次中的activity的父activity。系統(tǒng)使用這個(gè)值去實(shí)現(xiàn)默認(rèn)的導(dǎo)航行為,比如在安卓4.1(API等級(jí)16)或者更高的 Up navigation。你可以為安卓的舊版本提供相同的導(dǎo)航行為,使用 Support Library 和 展示的那樣來添加<meta-data>元素。
注意: 你的安卓SDK可能已經(jīng)包含了最近的安卓支持庫(support library)。它被包含在ADT包中,但是如果你使用不同的IDE,你可以在 添加平臺(tái)和包 Adding Platforms and Packages 時(shí) 安裝它。當(dāng)你使用Eclipse模板的時(shí)候,Support Library已經(jīng)自動(dòng)添加到你的應(yīng)用項(xiàng)目里了(你可以在庫的JAR文件 包里的Android Dependencies下面列出)。如果你不使用Eclipse,你需要手動(dòng)的添加庫到你的項(xiàng)目中,跟隨 setting up the Support Library 指南的方式,這時(shí)再回到這里。
如果你使用Eclipse開發(fā),現(xiàn)在你可以執(zhí)行應(yīng)用了,但是不會(huì)發(fā)生什么。點(diǎn)擊 Send發(fā)送按鈕開啟第二個(gè)Activity,但是使用了被通過模板提供的一個(gè)默認(rèn)的“hello world” 布局。你隨后會(huì)更改這個(gè)activity來替換顯示自定義的文本視圖,這樣如果你使用了其他的IDE,不要擔(dān)心應(yīng)用不能通過編譯。
收到Intent
每個(gè)Activity都通過intent的形式被調(diào)用,不管用戶通過掃描方式導(dǎo)航到那里。你能夠通過調(diào)用 getIntent() 獲得啟動(dòng)這個(gè)activity的Intent,和獲得在它里面包含的數(shù)據(jù)。
在DisplayMessageActivity 類 的 onCreate() 方法里,獲得intent和提取MainActivity傳遞而來的消息。
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
顯示消息
為了在屏幕上顯示消息, 創(chuàng)建一個(gè) TextView 組件,并且使用 setText() 設(shè)置文本. 這時(shí),添加代碼使用 setContentView(). TextView 作為 activity的布局的 根視圖 。
DisplayMessageActivity 的完整的 onCreate() 方法看起這樣:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the message from the intent
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
// Set the text view as the activity layout
setContentView(textView);
}
現(xiàn)在你可以啟動(dòng)應(yīng)用程序了。當(dāng)它打開時(shí),在文本框輸入一個(gè)消息,點(diǎn)擊發(fā)送,這時(shí)消息出現(xiàn)在第二個(gè)activity。
圖表2 。 在最終的應(yīng)用程序里的兩個(gè)activity,運(yùn)行在安卓4.4
這就是了,你完成構(gòu)建里你的第一個(gè)安卓應(yīng)用!