Android应用开发-快速入门
內(nèi)容摘要
- 了解Android 操作系統(tǒng)
- 搭建Android 開發(fā)工具
- 使用Android 模擬器
- 案例-電話撥號器/短信發(fā)送器
- 掌握點擊事件的四種實現(xiàn)方式
- 掌握Android 常見布局
- 了解Android 中的長度單位
1. 手機制式
手機的發(fā)展根據(jù)通信技術(shù)大致可以劃分為4 個時代(G:Generation 的縮寫)
第一代模擬制式手機(1G):1G就是大哥大,手機類似于簡單的無線電雙工電臺,通話是鎖定在一定頻率,所以使用可調(diào)頻電臺就可以竊聽通話
第二代GSM、CDMA等數(shù)字手機(2G):手機使用PHS,GSM或者CDMA這些十分成熟的標準,具有穩(wěn)定的通話質(zhì)量和合適的待機時間,支持彩信業(yè)務(wù)的GPRS和上網(wǎng)業(yè)務(wù)的WAP服務(wù),以及各式各樣的Java程序等
第三代移動通信技術(shù)(3G):3G,是英文3rd Generation的縮寫,指第三代移動通信技術(shù)。指將無線通信與國際互聯(lián)網(wǎng)等多媒體通信結(jié)合的新一代移動通信系統(tǒng)。它能夠處理圖像、音樂、視頻流等多種媒體形式,提供包括網(wǎng)頁瀏覽、電話會議、電子商務(wù)等多種信息服務(wù)
第四代移動電話行動通信(4G):4G。該技術(shù)包括TD-LTE和FDD-LTE兩種制式。4G是集3G與WLAN于一體,并能夠傳輸高質(zhì)量視頻圖像,它的圖像傳輸質(zhì)量與高清晰度電視不相上下。4G系統(tǒng)能夠以100Mbps的速度下載,比目前的撥號上網(wǎng)快200倍,并能夠滿足幾乎所有用戶對于無線服務(wù)的要求。此外,4G可以在DSL和有限電視調(diào)制解調(diào)器沒有覆蓋的地方部署,然后再擴展到整個地區(qū)
1G制式:徹底退出歷史舞臺……
2G/3G/4G的區(qū)別:網(wǎng)速的區(qū)別。
2G:打個電話給你:“我租了一張蒼老師的VCD,一起來看”。
3G:發(fā)個消息給你:“種子發(fā)你郵箱了,注意查收,請叫我雷鋒”。
4G:發(fā)個地址給你:“在線看,高清的,還能邊看邊吐槽”。
2G 撥號上網(wǎng),帶寬12.2k每用戶。
3G 寬帶上網(wǎng),帶寬384k~2M每用戶。
4G 光纖到戶,帶寬可以達到100M每用戶。
1.1 買手機注意網(wǎng)絡(luò)制式
- 2G制式:
- GSM:移動/聯(lián)通
- CDMA:電信
- 3G制式
- WCDMA:聯(lián)通
- TD-SCDMA:移動
- CDMA 2000:電信
- 4G制式
- FDD-LTE:電信/聯(lián)通
- TD-LTE(3個版本,對應(yīng)三大運營商,互不兼容):移動/電信/聯(lián)通
2. Android簡單歷史
2.1 安卓之父:安迪·魯賓
2003年10月,安迪·魯賓牽頭創(chuàng)建了一家公司,名為Android,開始開發(fā)一款針對手機端的操作系統(tǒng)。
2005年8月,谷歌低調(diào)收購了這家公司及其團隊,安迪·魯賓成為Google公司工程部副總裁,繼續(xù)負責Android項目。
2007年11月,谷歌公司正式向外界展示了這款名為Android的操作系統(tǒng),并宣布建立一個全球性的聯(lián)盟組織,該組織由34家手機制造商、軟件開發(fā)商、電信運營商以及芯片制造商共同組成,他們共同搭建起了Android系統(tǒng)最早的生態(tài)圈。
2011年,Android在全球的市場份額首次超過塞班系統(tǒng),躍居第一,目前的主要競爭對手是iOS。
2.2 Android進化史
- 2008 年9 月23 日Android 1.0 發(fā)布,代號Bender(發(fā)條機器人),這也是Android 系統(tǒng)最早的版本
- 2009 年9 月15 日Android 1.6 發(fā)布,代號Donut(甜甜圈)該版本首次支持了CDMA 網(wǎng)絡(luò)
- 2009 年11 月Android 2.0 發(fā)布,代號Eclair(松餅)無論從哪個方面說,它都是Android 發(fā)展歷史上第二個重要的里程碑時刻(第一個是Android1.5)
- 2010 年5 月20 日Android 2.2 發(fā)布,代號Froyo(凍酸奶)為Android 添加了很多企業(yè)級功能
- 2011 年10 月19 日Android 4.0 發(fā)布,代號Ice Cream Sandwich(冰激凌三明治)是Android 發(fā)展歷史上最重大的一次升級
- 2012 年6 月28 日Android 4.1 發(fā)布,代號Jelly Bean(果凍豆)是谷歌繼蜂巢之后,一次全新的平板策略嘗試
- 2014 年10 月15 日Android 5.0 發(fā)布,代號Lollipop(棒棒糖),全新的UI 設(shè)計,全新的操作系統(tǒng)
- 2015 年10 月6 日Android 6.0 發(fā)布,代號Marshmallow(棉花糖),這次的新版系統(tǒng)在UI 和交互上和Android 5.X 保持高度一致
- 2016年5月19日,谷歌在美國加州的山景城舉辦了 Google I/O 開發(fā)者大會中發(fā)布。2016年6月,Android N正式命名為“牛軋?zhí)恰?/li>
3. Android體系結(jié)構(gòu)
Android 的系統(tǒng)架構(gòu)采用了分層的設(shè)計。從架構(gòu)圖看,Android 分為四層,從低層到高層分別是Linux 內(nèi)核層、系統(tǒng)運行庫層、應(yīng)用程序框架層和應(yīng)用程序?qū)?/p>
3.1 LINUX KERNEL
Linux核心,Android系統(tǒng)是基于Linux系統(tǒng)修改過來的,Android底層都是Linux的東西,大多都是操作硬件的一些驅(qū)動,如Display Driver、Audio Drivers等,Linux 內(nèi)核也同時作為硬件和軟件棧之間的抽象層
3.2 LIBRARIES
用C語言編寫的完成Android核心功能的一些類庫,這些庫能被Android 系統(tǒng)中不同的組件使用。它們通過Android 應(yīng)用程序框架為開發(fā)者提供服務(wù)
- OpenGL|ES(圖形圖像引擎簡化版)
- WebKit(瀏覽器內(nèi)核)
- SQLite(輕量級數(shù)據(jù)庫)
- Surface Manager(界面管理器)
- Media Framework(多媒體框架)
- FreeType(字體類庫)
- SGL(另一個圖形圖像引擎)
- SSL(基于TCP的安全協(xié)議)
- libc(零散的類庫)
3.3 Android Runtime
- Core Libraries - 該核心庫提供了Java 編程語言核心庫的大多數(shù)功能
- Dalvik Virtual Machine
Android底層是Linux系統(tǒng),使用C、C++語言編寫的,所以Android程序(Java語言編寫)要在Linux上運行就需要虛擬機,也就是DVM。每一個Android 應(yīng)用程序都在它自己的進程中運行,都擁有一個獨立的Dalvik 虛擬機實例。Dalvik 虛擬機依賴于linux 內(nèi)核的一些功能,比如線程機制和底層內(nèi)存管理機制
3.4 APPLICATION FRAMEWORK
應(yīng)用框架層,全部是用Java語言編寫的,供開發(fā)人員調(diào)用。Android 系統(tǒng)中的每個應(yīng)用都依賴于該框架提供的一系列服務(wù)和系統(tǒng),其中包括:
- 活動管理器( Activity Manager) 用來管理應(yīng)用程序生命周期并提供常用的導航回退功能。
- 豐富而又可擴展的視圖(Views),可以用來構(gòu)建應(yīng)用程序, 它包括列表(lists),網(wǎng)格(grids),文本框(textboxes),按鈕(buttons),甚至可嵌入的web 瀏覽器。
- 內(nèi)容提供器(Content Providers)使得應(yīng)用程序可以訪問另一個應(yīng)用程序的數(shù)據(jù)(如聯(lián)系人數(shù)據(jù)庫), 或者共享它們自己的數(shù)據(jù)。
- 資源管理器(Resource Manager)提供非代碼資源的訪問,如本地字符串,圖形,和布局文件( layoutfiles )。
- 通知管理器(Notification Manager) 使得應(yīng)用程序可以在狀態(tài)欄中顯示自定義的提示信息。
3.5 APPLICATIONS
應(yīng)用層,我們安裝的所有應(yīng)用都屬于這一層,如,微信,植物大戰(zhàn)僵尸。該層不僅包括系統(tǒng)內(nèi)置的應(yīng)用也包括用戶自己安裝的應(yīng)用,比如email 客戶端,SMS短消息程序,日歷,地圖,瀏覽器,聯(lián)系人管理程序,QQ,微信,淘寶,美團等,該層所有的應(yīng)用程序都是使用Java語言編寫的
3.6 舉例:鬧鐘應(yīng)用
鬧鐘應(yīng)用的功能實際上就是定時播放音樂。鬧鐘應(yīng)用調(diào)用APPLICATION FRAMEWORK層的MediaPlayer,MeidaPlayer訪問LIBRARIES層中的Media Framework,Media Framework再使用C語言操作Andio Drivers去播放音樂
4. Dalvik VM和JVM的比較
JavaSE 程序使用的虛擬機叫Java Virtual Machine,簡稱JVM,Android 應(yīng)用也使用Java 語言開發(fā),但是使用的虛擬就是Dalvik Virtual Machine,簡稱DVM。
Dalvik 是Google 公司自己設(shè)計用于Android 平臺的Java 虛擬機。它執(zhí)行的是已轉(zhuǎn)換為.dex(即Dalvik Executable)格式的Java 應(yīng)用程序的運行,.dex 格式是專為Dalvik 設(shè)計的一種壓縮格式,適合內(nèi)存和處理器速度有限的系統(tǒng)。
Dalvik 經(jīng)過優(yōu)化,允許在有限的內(nèi)存中同時運行多個虛擬機的實例,并且每一個Dalvik 應(yīng)用作為一個獨立的Linux 進程執(zhí)行。獨立的進程可以防止在虛擬機崩潰的時候所有程序都被關(guān)閉。
DVM執(zhí)行的是.dex格式文件,JVM執(zhí)行的是.class格式文件。Android程序編譯完之后生成.class文件,然后,dex工具會把.class文件處理成.dex文件,然后把資源文件和.dex文件等打包成.apk文件,apk就是android package的意思。
4.1 DVM相比JVM運行效率更高的原因
每個jar包中都會有很多的class文件,每個class文件都有一個Header,Header中保存了class文件的初始信息,如,生成該class的jdk版本。而在apk文件中的dex文件,只有一個Header,所有class文件的初始信息都保存在其中,效率更高
每個class文件中有常量、字節(jié)碼、方法、域等保存自己的對應(yīng)的信息。dex文件中把所有class文件中的常量放在常量池中,所有class文件中的字節(jié)碼放到一個字節(jié)碼常量池中,等等。雖然這樣打包慢一點,但是讀取的時候會很快。
class文件存在很多的冗余信息,dex工具會去除冗余信息,并把所有的.class文件整合到.dex文件中,減少了I/O操作,提高了類的查找速度。
4.2 Dalvik 和標準Java 虛擬機(JVM)主要差別
Dalvik 基于寄存器,而JVM 基于棧。基于寄存器的虛擬機對于編譯后變大的程序來說,在它們執(zhí)行的時候,花費的時間更短。
Dalvik 和Java 運行環(huán)境的區(qū)別:
- Dalvik 主要是完成對象生命周期管理,堆棧管理,線程管理,安全和異常管理,以及垃圾回收等重要功能
- Dalvik 負責進程隔離和線程管理,每一個Android 應(yīng)用在底層都會對應(yīng)一個獨立的Dalvik 虛擬機實例,其代碼在虛擬機的解釋下得以執(zhí)行
- 不同于Java 虛擬機運行Java 字節(jié)碼,Dalvik 虛擬機運行的是其專有的文件格式Dex
- dex 文件格式可以減少整體文件尺寸,提高I/O 操作的類查找速度
- odex 是為了在運行過程中進一步提高性能,對dex 文件的進一步優(yōu)化
- 所有的Android 應(yīng)用的線程都對應(yīng)一個Linux 線程,虛擬機因而可以更多的依賴操作系統(tǒng)的線程調(diào)度和管理機制
- 有一個特殊的虛擬機進程Zygote,他是虛擬機實例的孵化器。它在系統(tǒng)啟動的時候就會產(chǎn)生,它會完成虛擬機的初始化,庫的加載,預制類庫和初始化的操作。如果系統(tǒng)需要一個新的虛擬機實例,它會迅速復制自身,以最快的數(shù)據(jù)提供給系統(tǒng)。對于一些只讀的系統(tǒng)庫,所有虛擬機實例都和Zygote 共享一塊內(nèi)存區(qū)域
- Dalvik 是由Dan Bornstein 編寫的,名字來源于他的祖先曾經(jīng)居住過名叫Dalvík 的小漁村,村子位于冰島
4.3 Android的新虛擬機ART
- ART 模式是什么?
ART 模式英文全稱為:Android runtime,谷歌從Android 4.4 系統(tǒng)開始新增的一種應(yīng)用運行模式,與傳統(tǒng)的Dalvik 模式不同,ART 模式可以實現(xiàn)更為流暢的Android 系統(tǒng)體驗。
在4.4 系統(tǒng)之前,Android 系統(tǒng)在Linux 的底層下構(gòu)筑Dalvik 一層的虛擬機,通過其可以更好適應(yīng)多樣的硬件架構(gòu),開發(fā)者只需要按一套規(guī)則進行應(yīng)用便可,無需因為不同的硬件架構(gòu)而處理與底層的驅(qū)動關(guān)系,從而大大提高開發(fā)的效率,但因為應(yīng)用均是運行在Dalvik 虛擬機中,因此應(yīng)用程序每次運行的時候,一部分代碼都需要重新進行編譯,這過程需要消耗一定的時間和降低應(yīng)用的執(zhí)行效率,最明顯的便是拖延了應(yīng)用的啟動時間和降低了運行速度。
- ART 模式有什么作用?
ART 模式最大的作用就是提升了Android 系統(tǒng)流暢度,相比Dalvik 模式中出現(xiàn)的耗電快、占用內(nèi)存大、即使是旗艦機用久了也會卡頓嚴重等現(xiàn)象,ART 模式中這種問題得到了很好的解決,通過在安裝應(yīng)用程序時,自動對程序進行代碼預讀取編譯,讓程序直接編譯成機器語言,免去了Dalvik 模式要時時轉(zhuǎn)換代碼,實現(xiàn)高效率、省電、占用更低的系統(tǒng)內(nèi)存、手機運行流暢。
- ART 模式的缺點
ART 模式可以降低手機硬件配置要求,減少RAM 內(nèi)存依賴,不過在安卓4.4 系統(tǒng)中,安裝應(yīng)用的時間比安卓4.4 以下版本系統(tǒng)更長,這主要由于應(yīng)用安裝過程中需要先執(zhí)行編碼導致,并且安裝應(yīng)用更占存儲空間(ROM)
Android 5.0以上版本的手機正式開始使用ART
4.4 DVM和ART虛擬機的區(qū)別
Dalvik:應(yīng)用程序每次運行的時候,字節(jié)碼都需要通過即時編譯器轉(zhuǎn)換為機器碼,這會拖慢應(yīng)用的運行效率。
ART:應(yīng)用在第一次安裝的時候,字節(jié)碼就會預先編譯成機器碼(java語言翻譯成C指令),使其成為真正的本地應(yīng)用,應(yīng)用的啟動和執(zhí)行速度都會顯著提升。弊端就是ART需要存儲java和C兩份指令,有些耗內(nèi)存。
上圖說明:進入開發(fā)者模式,選擇運行環(huán)境切換。在切換至ART模式時,系統(tǒng)會重新啟動,改變運行環(huán)境,需要等待程序優(yōu)化完畢,即可。
QQ實際占用內(nèi)用內(nèi)存,原本為44.64MB,ART模式下,變?yōu)?3.00MB,說明ART有些耗內(nèi)存(存兩份指令)。
5. Android開發(fā)環(huán)境搭建
目前主流的開發(fā)工具有兩個,一個是Eclipse 另外一個是Android Studio。Eclipse 需要和ADT(Android Develop Tool)插件整合后才能使用,不過Google 官方已經(jīng)直接提供了Eclipse 和ADT 集成好的開發(fā)工具,叫ADT-Bundle,但是現(xiàn)在Google已經(jīng)不再支持這種方式開發(fā),已經(jīng)完全轉(zhuǎn)移到Android Studio平臺
Android Studio 是Google 基于IntelliJ IDEA 開發(fā)的Android 集成開發(fā)工具,目前國內(nèi)使用該開發(fā)工具的企業(yè)也越來越多。Android 基礎(chǔ)階段我們依然使用Eclipse 作為開發(fā)工具,在后面的課程中才會使用到Android Studio。
獲取SDK工具包(Software development kits)下載地址、Android首頁、 Android中文版首頁
工具包,包含以下內(nèi)容:
- Eclipse+ADT插件
- Android SDK
- Android Platform-tools
- 最新的Android開發(fā)平臺
- 最新的模擬器鏡像
Android Studio是一個Android開發(fā)環(huán)境,基于IntelliJ IDEA,類似Eclipse ADT,Android Studio提供了集成的Android開發(fā)工具用于開發(fā)和調(diào)試。
6. SDK目錄結(jié)構(gòu)
雙擊SDK Manager.exe。
SDK文件夾目錄結(jié)構(gòu)(請對應(yīng)上圖查看):
- add-ons文件夾中保存著附加庫,比如Google Maps。
- build-tools文件夾中保存著編譯工具。
- tools文件中只有少數(shù)指令需要我們手動調(diào)用,如,draw9patch.bat。
- platform-tools文件夾中包含可執(zhí)行程序和批處理文件,其中adb.exe很重要。
- extras文件夾中v4表示最低可以支持到1.6版本,v7表示最低可以支持到1.7版本。
- temp文件夾為臨時目錄。
docs文件夾中是SDK幫助文檔,在線文檔使用起來很不方便。但是,我們可以使用離線文檔。雙擊sdk目錄下的docs文件夾,雙擊此文件夾中的index.html,雙擊打開。然后,會等待很久,因為瀏覽器要去google服務(wù)器請求數(shù)據(jù)。如果請求不到,就會一直請求,直到超時。如果斷網(wǎng)了,也就請求不到數(shù)據(jù)了
但是,我們可以脫機使用。步驟1、打開火狐,選擇“開發(fā)者”–>“脫機工作”。
步驟2、打開SDK離線文檔,可以搜索API。如,Activity。
2、安裝intel文件夾中的IntelHAXM.exe可能報錯。如果報錯為如下,說明本機不支持安裝HAXM.exe,不用裝了。
如果報錯如下,說明本機支持,但是支持加速器的選項沒有打開,去BIOS中打開即可。進入BIOS找到virtual technology選項,選擇enable即可。
7. 模擬器的創(chuàng)建
1、首先指定SDK的路徑。
點擊Windows–>preferences–>Android,默認指定正確的SDK路徑。但是,如果以前裝過SDK,那么就會指定舊的SDK,也就是錯誤的,手動更換成新的SDK路徑即可。
2、點擊虛擬機管理器按鈕–>點擊New,創(chuàng)建模擬器。
3、點擊“detail”可以看到模擬器配置明細。
4、點擊“Start”–>Launch,啟動模擬器。
不建議使用這么大的分辨率,屏幕分辨率越大,啟動越慢,最好用320*480的分辨率。
8. 創(chuàng)建Android項目
步驟1、右擊–>New–>Android Application Project。
步驟二、設(shè)置Android項目參數(shù)。
步驟三、設(shè)置應(yīng)用圖標。
步驟四、創(chuàng)建Activity。我們創(chuàng)建的時候都使用空白的Activity,需要什么效果,最好自己寫。自動生成的Activity,很多自動生成的代碼需要刪除、修改,很麻煩。
給Activity起個名字,一般就叫MainActivity,不需要修改。
步驟五、生成項目成功。
步驟六、空白項目也可以部署,運行。右擊–>Run As–>Android Application。
然后,此項目就會被部署到Android的模擬器上。選擇Console中的Android選項卡,可以看到部署的狀態(tài)。
步驟七、運行成功。
9. Android項目目錄結(jié)構(gòu)
示例1:更改應(yīng)用程序圖標、名稱。
1、 將圖標存入drawable-hdpi文件夾中。
2、查看R.java文件,可以看到生成了相應(yīng)的id。
3、打開AndroidManifest.xml文件,修改。
4、運行。
1、在AndroidManifest.xml文件中,修改圖標及應(yīng)用名稱時,一定要注意:如果activity標簽中沒有android:label及android:icon這兩個屬性,那么顯示的就是application標簽中的這兩個屬性的值,不存在覆蓋問題。但是,如果activity標簽中也有android:label及android:icon這兩個屬性,那么就會覆蓋application標簽中的android:label及android:icon屬性。也就是說,顯示的就是activity標簽中的這兩個屬性的值。
2、圖片3中的圖標及應(yīng)用名稱會始終依據(jù)AndroidManifest.xml文件中的application標簽中的android:icon和android:label兩個屬性值展示,因為此界面屬于管理頁面,要與圖1和圖2中的普通的Activity區(qū)分開。
示例2:修改展示內(nèi)容。
1、修改res中values文件夾中的strings.xml文件。
2、查看R.java文件,可以看到生成了相應(yīng)的id。
3、修改res中l(wèi)ayout文件夾中的布局文件activity_mainxml。
4、運行。
10. 應(yīng)用打包安裝過程
1、Android項目編譯、打包成apk.apk中包含
- .dex文件
- resources.arsc(apk中的“配置文件”、“布局文件”、“圖片”的索引)
- uncompiled resources(未編譯的資源,res文件下的資源都是不會被編譯的,res文件夾下的圖片、布局文件都是原封不動的打包到apk中)
- 清單文件(AndroidManifest.xml,也會被原封不動的打包進apk中)
PS:被編譯的只有.java代碼
2、簽名(給apk包打個數(shù)字簽名)。然后再通過ADB運行到Devices emulator上,Devices指的是手機,Emulator指的是模擬器。系統(tǒng)判斷兩個應(yīng)用是否屬于同一款應(yīng)用,首先先確認清單文件中Manifest標簽的package屬性值(應(yīng)用程序在系統(tǒng)中的唯一標識)是否相同,其次判斷簽名是否相同。只有兩個都相同,才會存在高版本覆蓋低版本的情況。也就是說,只有簽名相同或者包名相同,是無法覆蓋的。簽名是屬于企業(yè)商業(yè)機密,是不能被他人獲取的。簽名是用一個key文件(相當于是秘鑰)計算出來的一個字符串,不同的秘鑰生成的字符串肯定不同,不同公司的簽名也是不同的。所以,一般是無法山寨另一個公司的應(yīng)用程序的。
PS:1、啟動應(yīng)用程序后,通過LogCat(LogCat展示的是Android模擬器的后臺輸出)可以看到一個應(yīng)用程序的包名。
2、在Android里面,安裝一個應(yīng)用程序是不能選路徑的。
通過點擊Window–>Show View–>Other…–>Android–>File Explorer,可以查看Android設(shè)備的文件目錄結(jié)構(gòu)。
3、所有第三方應(yīng)用(也就是可以刪除的項目)安裝在data/app目錄下,并且apk文件名是以包名命名的。
4、所有系統(tǒng)應(yīng)用(不可以刪除的項目)都安裝在system/app目錄下。
11. DDMS
DDMS 是Dalvik Debug Monitor Service 的簡稱。DDMS 為IDE 和emulator 以及Android 真機架起來了一座橋梁。開發(fā)人員可以通過DDMS 看到目標機器上運行的進程/線程狀態(tài),可以看進程的heap 信息,可以查看logcat 信息,可以查看進程分配內(nèi)存情況,可以向目標機發(fā)送短信以及打電話,可以向Android發(fā)送地理位置信息。下面以Eclipse 的DDMS perspective 為例簡單介紹DDMS 的功能
1、Devices選項卡用來查看與開發(fā)環(huán)境建立連接的Android設(shè)備,在這里是模擬器,也可以是真機。
2、SD卡所在的目錄為storage/sdcard。
3、Emulator Control為控制模擬器的選項卡。
PS:1、這里有個bug,一旦用模擬器打電話,連接就會終端。只需要點擊Devices選項卡右邊的小三角–>Reset ADB,重啟ADB即可。
2、DDMS中所有的選項卡都可以在Java中使用,只需要切換到Java透視圖,點擊Window–>show View,選擇需要的選項卡即可。
12. 常用ADB指令
ADB,Android debug bridge Android調(diào)試橋,用于建立Android設(shè)備與開發(fā)環(huán)境的連接。
模擬器中的操作日志原本是不可能在Windows平臺上輸出的。但是,正是由于有了ADB,所以LogCat中才可以輸出模擬器中的操作日志。
1、ADB是一個可執(zhí)行的指令,在CMD中使用,使用前首先配置環(huán)境變量。
ADB相關(guān)指令功能介紹:
adb install xxx.apk:把一個apk安裝到模擬器中。
adb uninstall 應(yīng)用包名:從模擬器中卸載一個apk。
adb devices:查看當前跟eclipse建立連接的Android設(shè)備。
PS:adb同時也是個進程,如果這個進程掛掉了,Android設(shè)備和開發(fā)環(huán)境連接就會中斷。
示例:
1、打開“任務(wù)管理器”–>點擊“adb.exe”–>點擊“結(jié)束進程”。
2、可以看到?jīng)]有任何Android設(shè)備再連接到模擬器上了。
3、通過控制臺,我們可以看到經(jīng)過11秒嘗試連接后,ADB連接重新恢復。
4、11秒時間太長,我們可以使用adb kill-server殺死adb進程,通過adb start-server開啟adb。
可以看到經(jīng)過不用花11秒,ADB就已經(jīng)啟動了。
5、通過adb devices也可以重啟ADB。
adb shell:進入Android的命令行,其實是Linux的命令行。
示例:
1、可以通過ls指令查看當前目錄結(jié)構(gòu)。
2、可以通過cd data進入data目錄,然后再通過ls查看data下的目錄結(jié)構(gòu)。
3、通過ps可以查看當前Android設(shè)備上運行的所有的進程,包括C進程和Java進程。
4、在Devices中看到的都是Java進程,可以通過“stop”按鈕關(guān)掉進程。例如,關(guān)掉sms(短信)進程。
PS
如果連接ADB時出現(xiàn)emulator-5554 offline,那就必須通過重啟模擬器解決了。
如果感覺模擬器太慢,可以通過真機測試,速度更快一些。有些測試模擬器更方便一些,因為真機有些目錄結(jié)構(gòu)是無法查看的。
有些進程是不能關(guān)閉的,例如com.android.launcher進程,關(guān)了,Android就會崩潰。不過關(guān)閉之后,它會自動重啟。
某些時候,通過adb start-server啟動adb會失敗,可能就是5037端口被占用了。例如,360手機助手,騰訊手機管家都有可能占用此端口。可以通過netstat -ano查看是哪個進程占用了5037端口。如下圖中可以看到,pid(如果看不到,那么點擊任務(wù)管理器–>選擇列–>勾上PID即可)為1848的進程占用了5037端口,而pid為1848的進程目前正是adb進程。如果不是adb進程,那么就直接殺掉占用5037端口的進程,然后重新啟動adb進程即可。
13. 電話撥號器
撥號器只負責撥號功能,打電話功能是通過切換到打電話的應(yīng)用實現(xiàn)的。撥號器應(yīng)用可以替換,但是打電話應(yīng)用是無法替代的,只能使用Android自己的打電話應(yīng)用。原因是與打電話相關(guān)的API,上層應(yīng)用是無法調(diào)用的,只有系統(tǒng)級別的應(yīng)用才能調(diào)用。也就是說打電話相關(guān)的API在Android jar包中都是不存在的。但是,這些API在源碼中是可以查看的。
步驟一、創(chuàng)建項目。
步驟二、寫布局文件,打開res\layout\activity_main.xml,編輯。
res\layout\activity_main.xml
<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:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:orientation="vertical"tools:context=".MainActivity" ><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="請輸入號碼:"android:textSize="18sp" /><EditText android:id="@+id/et"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="請輸入號碼"/><Button android:id = "@+id/bt"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="撥打"/> </LinearLayout>PS
TextView用來顯示文本。
layout_width,layout_height是定義文本寬高的,默認值是wrap_content,表示正好能夠緊緊包裹文本內(nèi)容的寬高,也就是文本大小決定寬高多少。layout_width,layout_height有3個屬性值,fill_parent與match_parent都是一樣的,表示填充父元素。在上面的代碼中也就是填充滿LinearLayout(線性布局)。可以看到LinearLayout的layout_width、layout_height也是填充滿父元素,也就是填充滿手機屏幕。但是,并沒有填充滿。原因在于paddingBottom、paddingTop、paddingLeft、paddingRight等屬性也決定了其與父元素(手機屏幕)的內(nèi)間距大小。
Android不推薦使用像素,長度用dp,字體大小用sp,不要使用像素,因為像素在屏幕適配時很難做。
布局類型在這里使用LinearLayout(現(xiàn)形布局)而不是RelativeLayout(相對布局)的原因在于線性布局不存在元素重疊的情況,而相對布局則存在。
LinearLayout的屬性android oritation表示排列方式,有兩種,vertical(垂直排列)和horizontal(水平排列)。
EditText用來展示輸入框。
EditText中的屬性hint表示:如果文本框中有內(nèi)容,就不顯示提示內(nèi)容;如果文本框沒有內(nèi)容,就會顯示提示內(nèi)容。
步驟三、寫java代碼,打開src\cn.itcast.dialer\MainActivity.java,編輯。
src\cn.itcast.dialer\MainActivity.java
package cn.itcast.dialer; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity {//onCreate方法是被系統(tǒng)在創(chuàng)建Activity時調(diào)用的。@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//設(shè)置按鈕點擊偵聽//通過資源id來獲取指定的組件的對象Button bt = (Button) findViewById(R.id.bt);//設(shè)置點擊偵聽bt.setOnClickListener(new MyListener());}//這里的OnClickListener的全名為:android.view.View.OnClickListenerclass MyListener implements OnClickListener {//按鈕按下時,此方法被調(diào)用@Overridepublic void onClick(View v) {//findViewById返回的是布局所有組件的父類android.view.View,需要強轉(zhuǎn)EditText et = (EditText) findViewById(R.id.et);//拿到用戶輸入的號碼String phone = et.getText().toString();//告訴系統(tǒng),我們的動作//1. 創(chuàng)建意圖對象Intent intent = new Intent();//2. 設(shè)置動作intent.setAction(intent.ACTION_CALL);//3. 設(shè)置號碼,通過Uri轉(zhuǎn)intent.setData(Uri.parse("tel:" + phone));//4. 把動作告訴系統(tǒng),開啟打電話應(yīng)用的ActivitystartActivity(intent);} } }14. 關(guān)聯(lián)源碼的方法
在Android Studio下,無需關(guān)聯(lián)源碼直接點擊即可查看源碼,因為Android Studio會自動反編譯源碼
1、Ctrl+左鍵,點擊某個類,再點擊Attach Source按鈕。
2、點擊External Folder…
3、選擇關(guān)聯(lián)sdk\sources\android-18
看到源碼,則說明關(guān)聯(lián)成功。
步驟四、試運行,可以看到出現(xiàn)了安全異常,沒有權(quán)限。因為打電話是需要費用的,所以需要出示權(quán)限。
步驟五、添加權(quán)限。
打開清單文件AndroidManifest.xml,使用可視化方式,點擊Permission選項卡–>Add–>Uses Permission。
添加Uses Permission的屬性“android.permission.CALL_PHONE”,Ctrl+S保存。
可以看到清單文件代碼中生成了如下代碼。
步驟六、重新運行,可以看到,撥打成功。
15. 點擊事件的實現(xiàn)
代碼:三種java寫法。
res\layout\activity_main.xml
<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:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity"android:orientation="vertical"><Button android:id="@+id/bt_iq"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="點我一下,云鶴智商-10" /><Button android:id="@+id/bt_eq"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="點我一下,云鶴情商-10" /></LinearLayout>src\cn.itcast.clickevent\MainActivity.java
package cn.itcast.clickevent;import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;public class MainActivity extends Activity implements OnClickListener{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button bt_iq = (Button) findViewById(R.id.bt_iq);Button bt_eq = (Button) findViewById(R.id.bt_eq);//第一種:Java寫法,內(nèi)部類實現(xiàn)OnClickListener接口,上個案例中就是按照內(nèi)部類的方法實現(xiàn)的。//第二種:Java寫法,匿名內(nèi)部類實現(xiàn)OnClickListener接口。bt_iq.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {System.out.println("點我一下,云鶴智商-10");}});bt_eq.setOnClickListener(this);}//第三種:Java寫法,當前類實現(xiàn)OnClickListener接口。@Overridepublic void onClick(View v) {System.out.println("點我一下,云鶴情商-10");}}運行結(jié)果:
代碼:Android寫法。
res\layout\activity_main.xml
<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:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity"android:orientation="vertical"><Button android:id="@+id/bt1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="按鈕1"android:onClick="click1"/><Button android:id="@+id/bt2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="按鈕2"android:onClick="click1" /><Button android:id="@+id/bt3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="按鈕3"android:onClick="click1" /></LinearLayout>src\cn.itcast.clickevent\MainActivity.java
package cn.itcast.clickevent;import android.app.Activity; import android.os.Bundle; import android.view.View;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}//Android寫法。//注意:1. 在Activity中定義。// 2. 方法名必須與Button的onClick屬性值相同。// 3. 返回值必須為void。// 4. 參數(shù)必須為View類型對象。系統(tǒng)調(diào)用此方法時,會把觸發(fā)的對象傳進來。這里就是按鈕,Button是View的子類。// 5. 多個按鈕Button的onClick屬性值可以相同,點擊任何一個按鈕都會調(diào)用相同的方法。通過id可以判斷用戶按下的是哪一個按鈕。public void click1(View v) {int id = v.getId();switch(id){case R.id.bt1:System.out.println("按鈕1被按下");break;case R.id.bt2:System.out.println("按鈕2被按下");break;case R.id.bt3:System.out.println("按鈕3被按下");break;}}}運行結(jié)果:
16. 短信發(fā)送器
代碼:res\layout\activity_main.xml
<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:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity"android:orientation="vertical"><!-- android:inputType="phone"表示只能輸入電話號碼 --><EditText android:id="@+id/et_phone"android:layout_width="wrap_content"android:layout_height="wrap_content"android:hint="請輸入號碼"android:inputType="phone" /><!-- android:lines="5"表示只能輸入5行 --><EditText android:id="@+id/et_content"android:layout_width="wrap_content"android:layout_height="wrap_content"android:hint="請輸入內(nèi)容"android:lines="5"/><Button android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="發(fā)送"android:onClick="send"/></LinearLayout>src\cn.itcast.smssender\MainActivity.java
package cn.itcast.smssender;import java.util.ArrayList;import android.app.Activity; import android.os.Bundle; import android.telephony.SmsManager; import android.view.View; import android.widget.EditText;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void send(View v) {//獲取用戶輸入的號碼和數(shù)據(jù)EditText et_phone = (EditText) findViewById(R.id.et_phone);EditText et_content = (EditText) findViewById(R.id.et_content);String phone = et_phone.getText().toString();String content = et_content.getText().toString();//獲取發(fā)送短信的API//SmsManager要使用android.telephony包內(nèi)的,不要使用android.telephony.gsm包內(nèi)的,已過時。SmsManager sm = SmsManager.getDefault();//如果短信過長,發(fā)布出去,可以把長短信拆分成若干條短短信。ArrayList<String> smss = sm.divideMessage(content);for(String str : smss){//第一個參數(shù)表示對方號碼。//第二個參數(shù)表示短信服務(wù)中心的號碼,可以傳null,表示使用默認的短信服務(wù)中心地址。//第三個參數(shù)表示短信內(nèi)容。//第四個參數(shù)表示廣播,如果不傳null,短信發(fā)送成功或失敗時,會給予回執(zhí)信息。//第五個參數(shù)表示如果對方成功接收信息了,會給予回執(zhí)信息。sm.sendTextMessage(phone, null, str, null, null);}}}添加權(quán)限:
運行結(jié)果:
1、發(fā)送一般短信結(jié)果。
2、發(fā)送超長短信結(jié)果。
17. dp和px
dp最終顯示長度多少是根據(jù)屏幕密度來換算的,屏幕越大,1dp就能顯示更長的像素。
320x480屏幕上,1dp=1px,160dp=160px,正好是屏幕寬度的一般。
480x800屏幕上,1dp=1.5px,160dp=240px,正好是屏幕寬度的一般
sp與dp類似,只是sp用于字體大小,dp用于長度大小。
res\layout\activity_main.xml
<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:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity" ><TextView android:layout_width="160px"android:layout_height="wrap_content"android:text="@string/hello_world"android:background="#ff0000"android:textSize="15sp"/><TextView android:layout_width="160dp"android:layout_height="wrap_content"android:text="@string/hello_world"android:background="#ff0000"android:textSize="15sp"/></LinearLayout>運行結(jié)果:
320x480屏幕下顯示:
480x800屏幕下顯示:
18. 布局介紹
為適應(yīng)各種界面風格,滿足開發(fā)的需要,Android提供了6種布局方式
- LinearLayout(線性布局)
- RelativeLayout(相對布局)
- FrameLayout(幀布局)
- TableLayout(表格布局)
- AbsoluteLayout(絕對布局)
- GridLayout(網(wǎng)格布局)
通過這6種布局我們可以做出來各種復雜的UI效果。
18.1 線性布局LinearLayout
- orientation屬性是指定線性布局的排列方向:
- horizontal 水平
- vertical 垂直
示例1:res\layout\activity_main.xml
<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"tools:context=".MainActivity"android:orientation="vertical"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="第一個" /><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="第二個" /><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="第三個" /></LinearLayout>運行結(jié)果:
1、設(shè)置android: orientation為vertical結(jié)果。
2、設(shè)置android: orientation為horizontal結(jié)果。
gravity屬性是指定當前控件內(nèi)容顯示位置:
- left 左邊
- right 右邊
- top 上邊
- bottom 底邊
示例2:res\layout\activity_main.xml
<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"tools:context=".MainActivity"android:orientation="vertical"><TextView android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:text="第一個"android:background="#ff0000"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_horizontal"android:text="第二個"android:background="#00ff00"/></LinearLayout>運行結(jié)果:
設(shè)置第一個TextView的android:layout_width屬性值為match_parent,由于父組件足夠?qū)?#xff0c;因此設(shè)置第一個TextView的android:gravity屬性值為center_horizontal,可以看到控件內(nèi)容居中。但是,第二個TextView的父組件寬高都是由包裹著內(nèi)容決定的,所以,設(shè)置第二個TextView的android:gravity起不到任何效果。
layout_gravity屬性是指定當前控件在父元素的位置:
- left 左邊
- right 右邊
- top 上邊
- bottom 底邊
示例3:res\layout\activity_main.xml
<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"tools:context=".MainActivity"android:orientation="vertical"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="第一個"android:background="#ff0000"android:layout_gravity="right"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="第二個"android:background="#00ff00"android:layout_gravity="center_horizontal"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="第三個"android:layout_gravity="bottom"/></LinearLayout>運行結(jié)果:
設(shè)置第一個TextView的android:layout_gravity屬性值為right,設(shè)置第二個TextView的android:layout_gravity屬性值為center_horizontal,設(shè)置第三個TextView的android:layout_gravity屬性值為bottom。然后會發(fā)現(xiàn),第三個TextView的設(shè)置將不會有任何效果。因為,
在線性布局中,豎直排列(vertical)時,頂部、底部、豎直居中對齊都無效。水平排列(horizontal)時,左右對齊,水平居中對齊都無效。
layout_weightSum(權(quán)重)屬性是把線性布局中剩余空間分成N份。
layout_weight (權(quán)重)屬性是指定當前控件在父元素(線性布局)中占N份。
示例4:res\layout\activity_main.xml
<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"tools:context=".MainActivity"android:orientation="horizontal"><TextView android:layout_width="match_parent"android:layout_height="wrap_content"android:text="第一個"android:background="#ff0000"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="第二個"android:background="#00ff00"/><TextView android:layout_width="match_parent"android:layout_height="wrap_content"android:text="第三個"android:background="#0000ff"/></LinearLayout>運行結(jié)果:
水平排列(horizontal)時,設(shè)置第一個TextView的android:layout_width屬性值為match_parent,將會發(fā)現(xiàn)第二個、第三個TextView被第一個TextView完全擠出去,看不到了。這時候就需要使用權(quán)重來解決這個問題。
示例5:res\layout\activity_main.xml
<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"tools:context=".MainActivity"android:orientation="horizontal"android:weightSum="2"><TextView android:layout_width="100dp"android:layout_height="wrap_content"android:text="第一個"android:background="#ff0000"android:layout_weight="1"/><TextView android:layout_width="100dp"android:layout_height="wrap_content"android:text="第二個"android:background="#00ff00"android:layout_weight="1"/></LinearLayout>運行結(jié)果:
首先,將第一個、第二個TextView的android:layout_width的屬性值分別設(shè)置為100dp。然后,通過為LinearLayout標簽設(shè)置android:layout_weightSum屬性值,把屏幕的總寬度權(quán)重設(shè)置為2,每個TextView的寬度權(quán)重通過android:layout_weight屬性設(shè)置為1,也就是平均分配。
但是,如果將第一個TextView的android:layout_width屬性值設(shè)置為100dp,將第二個TextView的android:layout_width屬性值設(shè)置為50dp,結(jié)果如下。
說明:android:weightSum及android:weight的屬性值設(shè)置,針對的是剩余空間的分配。
第一次分配情況如下:
第二次分配情況如下:
所以,當排列為水平排列(horizontal),利用權(quán)重進行分配的時候,一定要搭配將android:layout_width屬性值設(shè)置為0dp來使用,這樣很容易計算。同理,當排列為垂直排列(vertical),在利用權(quán)重進行分配的時候,一定要搭配將android:layout_height屬性值設(shè)置為0dp來使用。
PS:
- android:weightSum是可以不寫的,上例中,如果第一個TextView的android:weight屬性值設(shè)置為1,第二個TextView的android:weight屬性值設(shè)置為2,那么weightSum即為3,兩個TextView按照1:2分配。但是,如果weightSum設(shè)置為4,相當于把寬度切成四份,前面3份,兩個TextView按照1:2分配,第4塊不分配。
- TextView的android:weight屬性如果不寫,相當于android:weight的屬性值為0,也就是不會分配到剩余空間任何部分。此時,如果android:layout_width屬性值設(shè)置為0dp,那么就會報錯。因為,此TextView已經(jīng)無法顯示出來了。
visibility屬性是控制布局是否顯示:
- visible 顯示
- invisible 不顯示但占空間
- gone 隱藏
練習:做出如下效果的布局。
實現(xiàn):右擊res/layout文件夾–>點擊New–>Android XML File–>選擇LinearLayout–>取一個名字。
代碼:res\layout\linearlayout_demo.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><LinearLayout android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:orientation="horizontal"><TextView android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="#000000"/><TextView android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="#ffffff"/><TextView android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="#ff0000"/><TextView android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="@android:color/darker_gray"/></LinearLayout><LinearLayout android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:orientation="vertical"><TextView android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="#00ffff"/><TextView android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="#ffffff"/><TextView android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="#ff0000"/><TextView android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="@android:color/darker_gray"/></LinearLayout></LinearLayout>運行結(jié)果:
PS:@android:color/darker_gray表示引用Android定義好的顏色資源id
總結(jié)
以上是生活随笔為你收集整理的Android应用开发-快速入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android应用开发:数据存储和界面展
- 下一篇: Android应用开发:网络编程-1