版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Android編程指南1-11章(共37章)目錄\h第1章Android應(yīng)用初體驗\h1.1應(yīng)用基礎(chǔ)\h1.2創(chuàng)建Android項目\h1.3Eclipse工作區(qū)導(dǎo)航\h1.4用戶界面設(shè)計\h1.5從布局XML到視圖對象\h1.6組件的實際應(yīng)用\h1.7使用模擬器運行應(yīng)用\h1.8Android編譯過程\h第2章Android與MVC設(shè)計模式\h2.1創(chuàng)建新類\h2.2Android與MVC設(shè)計模式\h2.3更新視圖層\h2.4更新控制層\h2.5在設(shè)備上運行應(yīng)用\h2.6添加圖標(biāo)資源\h2.7關(guān)于挑戰(zhàn)練習(xí)\h2.8挑戰(zhàn)練習(xí)一:為TextView添加監(jiān)聽器\h2.9挑戰(zhàn)練習(xí)二:添加后退按鈕\h2.10挑戰(zhàn)練習(xí)三:從按鈕到圖標(biāo)按鈕\h第3章Activity的生命周期\h3.1日志跟蹤理解Activity生命周期\h3.2設(shè)備旋轉(zhuǎn)與Activity生命周期\h3.3設(shè)備旋轉(zhuǎn)前保存數(shù)據(jù)\h3.4再探Activity生命周期\h3.5深入學(xué)習(xí):測試onSaveInstanceState(Bundle)方法\h3.6深入學(xué)習(xí):日志記錄的級別與方法\h第4章Android應(yīng)用的調(diào)試\h4.1DDMS應(yīng)用調(diào)試透視圖\h4.2異常與棧跟蹤\h4.3文件瀏覽器\h4.4Android特有的調(diào)試工具\h第5章第二個activity\h5.1創(chuàng)建第二個activity\h5.2啟動activity\h5.3activity間的數(shù)據(jù)傳遞\h5.4activity的使用與管理\h5.5挑戰(zhàn)練習(xí)\h第6章AndroidSDK版本與兼容\h6.1AndroidSDK版本\h6.2Android編程與兼容性問題\h6.3使用Android開發(fā)者文檔\h6.4挑戰(zhàn)練習(xí):報告編譯版本\h第7章UIfragment與fragment管理器\h7.1UI設(shè)計的靈活性需求\h7.2fragment的引入\h7.3著手開發(fā)CriminalIntent\h7.4托管UIfragment\h7.5創(chuàng)建UIfragment\h7.6添加UIfragment到FragmentManager\h7.7activity使用fragment的理由\h7.8深入學(xué)習(xí):Honeycomb、ICS、JellyBean以及更高版本系統(tǒng)上的應(yīng)用開發(fā)\h第8章使用布局與組件創(chuàng)建用戶界面\h8.1升級Crime類\h8.2更新布局\h8.3生成并使用組件\h8.4深入探討XML布局屬性\h8.5使用圖形布局工具\h8.6挑戰(zhàn)練習(xí):日期格式化\h第9章使用ListFragment顯示列表\h9.1更新CriminalIntent應(yīng)用的模型層\h9.2創(chuàng)建ListFragment\h9.3使用抽象activity托管fragment\h9.4ListFragment、ListView及ArrayAdapter\h9.5定制列表項\h第10章使用fragmentargument\h10.1從fragment中啟動activity\h10.2fragmentargument\h10.3重新加載顯示列表項\h10.4通過fragment獲取返回結(jié)果\h第11章使用ViewPager\h11.1創(chuàng)建CrimePagerActivity\h11.2深入學(xué)習(xí):ViewPager的工作原理\h第12章對話框\h12.1創(chuàng)建DialogFragment\h12.2fragment間的數(shù)據(jù)傳遞\h12.3挑戰(zhàn)練習(xí):更多對話框第1章Android應(yīng)用初體驗本章將介紹編寫Android應(yīng)用需掌握的一些新的概念和UI組件。學(xué)完本章,如果沒能理解全部內(nèi)容,也不必?fù)?dān)心。后續(xù)章節(jié)還會有更加詳細(xì)的講解,我們將再次溫習(xí)并理解這些概念。馬上要編寫的首個應(yīng)用名為GeoQuiz,它能測試用戶的地理知識。用戶通過單擊True或False按鈕來回答屏幕上的問題,GeoQuiz可即時反饋答案正確與否。圖1-1顯示了用戶點擊False按鈕的結(jié)果。圖1-1正確答案應(yīng)該是伊斯坦布爾(Istanbul),而不是君士坦丁堡1.1應(yīng)用基礎(chǔ)GeoQuiz應(yīng)用由一個activity和一個布局(layout)組成。activity是AndroidSDK中Activity類的一個具體實例,負(fù)責(zé)管理用戶與信息屏的交互。應(yīng)用的功能是通過編寫一個個Activity子類來實現(xiàn)的。簡單的應(yīng)用可能只需一個子類,而復(fù)雜的應(yīng)用則會有多個子類。GeoQuiz是個簡單應(yīng)用,因此它只有一個名為QuizActivity的Activity子類。QuizActivity管理著圖1-1所示的用戶界面。布局定義了一系列用戶界面對象以及它們顯示在屏幕上的位置。組成布局的定義保存在XML文件中。每個定義用來創(chuàng)建屏幕上的一個對象,如按鈕或文本信息。GeoQuiz應(yīng)用包含一個名為activity_quiz.xml的布局文件。該布局文件中的XML標(biāo)簽定義了圖1-1所示的用戶界面。QuizActivity與activity_quiz.xml文件的關(guān)系如圖1-2所示。圖1-2QuizActivity管理著activity_quiz.xml文件定義的用戶界面學(xué)習(xí)了這些基本概念后,我們來創(chuàng)建本書第一個應(yīng)用。1.2創(chuàng)建Android項目首先我們來創(chuàng)建一個Android項目。Android項目包含組成一個應(yīng)用的全部文件。啟動Eclipse程序,選擇File→New→AndroidApplicationProject菜單項,打開新建應(yīng)用窗口來創(chuàng)建一個新的項目。在應(yīng)用名稱(ApplicationName)處輸入GeoQuiz,如圖1-3所示。此時項目名稱(ProjectName)會自動更新為GeoQuiz。在包名處(PackageName)輸入com.bignerdranch.android.geoquiz。圖1-3創(chuàng)建新應(yīng)用注意,以上輸入的包名遵循了“DNS反轉(zhuǎn)”約定,亦即將企業(yè)組織或公司的域名反轉(zhuǎn)后,在尾部附加上應(yīng)用名稱。遵循此約定可以保證包名的唯一性,這樣,同一設(shè)備和GooglePlay商店的各類應(yīng)用就可以區(qū)分開來。接下來的四個選項用來配置應(yīng)用如何與不同版本的Android設(shè)備適配。GeoQuiz應(yīng)用只需使用默認(rèn)設(shè)置,所以現(xiàn)在可以忽略它們。第6章將介紹Android不同版本的差異。Android開發(fā)工具每年會更新多次,因此當(dāng)前的向?qū)М嬅婵雌饋砜赡軙c本書略有不同。這一般不是問題,工具更新后,向?qū)М嬅娴呐渲眠x項應(yīng)該不會有太大差別。(如果向?qū)М嬅婵雌饋泶笥胁煌?,可以肯定開發(fā)工具已進(jìn)行了重大更新。不要擔(dān)心,請訪問本書論壇\h,學(xué)習(xí)如何使用最新版本的開發(fā)工具。)現(xiàn)在單擊Next按鈕。在第二個窗口中,清除已勾選的創(chuàng)建定制啟動圖標(biāo)(Createcustomlaunchericon)選項,如圖1-4所示。GeoQuiz應(yīng)用只需使用默認(rèn)的啟動圖標(biāo)。最后確認(rèn)創(chuàng)建activity(Createactivity)選項已選中。圖1-4配置項目單擊Next按鈕繼續(xù)。圖1-5所示的窗口詢問想要創(chuàng)建的activity類型。選擇BlankActivity。圖1-5創(chuàng)建新的activity單擊Next按鈕。在應(yīng)用向?qū)У淖詈笠粋€窗口,命名activity子類為QuizActivity,如圖1-6所示。注意子類名的Activity后綴。盡管不是必需的,但我們建議遵循這一好的命名約定。圖1-6配置新建的activity為體現(xiàn)布局與activity間的對應(yīng)關(guān)系,布局名稱(LayoutName)會自動更新為activity_quiz。布局的命名規(guī)則是:將activity名稱的單詞順序顛倒過來并全部轉(zhuǎn)換為小寫字母,然后在單詞間添加下劃線。對于后續(xù)章節(jié)中的所有布局以及將要學(xué)習(xí)的其他資源,建議統(tǒng)一采用這種命名風(fēng)格。保持導(dǎo)航類型(NavigationType)的None選項不變,單擊Finish按鈕。Eclipse完成創(chuàng)建并打開新的項目。1.3Eclipse工作區(qū)導(dǎo)航如圖1-7所示,Eclipse已在工作區(qū)窗口(workbenchwindow)里打開新建項目。(注意,如是安裝后初次使用Eclipse,則需關(guān)閉初始的歡迎窗口,才能看到如圖所示的工作區(qū)窗口。)圖1-7調(diào)整安排工作區(qū)窗口整個工作區(qū)窗口分為不同的區(qū)域,這里統(tǒng)稱為視圖。最左邊是包瀏覽器(packageexplorer)視圖,通過它可以管理所有項目相關(guān)的文件。中間部分是代碼編輯區(qū)(editor)視圖。為便于開發(fā),Eclipse默認(rèn)在代碼編輯區(qū)打開了activity_quiz.xml文件。在工作區(qū)的右邊以及底部還有一些其他視圖。通過點擊視圖名稱旁邊的x關(guān)閉標(biāo)志,可關(guān)閉右邊的各種視圖,如圖1-7所示。底部的視圖以分組面板(tabgroup)形式顯示??赏ㄟ^右上角的控制功能最小化整個分組面板,而不是全部關(guān)閉它們。視圖被最小化后,聚縮到了Eclipse工作區(qū)邊緣區(qū)域的工具欄上。移動鼠標(biāo)到工具欄的任意圖標(biāo)上,即可看到對應(yīng)視圖的名字,點擊圖標(biāo)可恢復(fù)對應(yīng)視圖。1.4用戶界面設(shè)計如前所述,Eclipse已默認(rèn)打開activity_quiz.xml布局文件,并在Android圖形布局工具里顯示了預(yù)覽界面。雖然圖形化布局工具非常好用,但為更好地理解布局的內(nèi)部原理,我們還是先學(xué)習(xí)如何使用XML代碼來定義布局。在代碼編輯區(qū)的底部選擇標(biāo)為activity_quiz.xml的標(biāo)簽頁,從預(yù)覽界面切換到XML代碼界面。當(dāng)前,activity_quiz.xml文件定義了默認(rèn)的activity布局。應(yīng)用的默認(rèn)布局經(jīng)常改變,但其XML布局文件卻總是與代碼清單1-1文件相似。代碼清單1-1默認(rèn)的activity布局(activity_quiz.xml)<RelativeLayoutxmlns:android="/apk/res/android"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".QuizActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world"/>
</RelativeLayout>首先,我們注意到activity_quiz.xml文件不再包含指定版本聲明與文件編碼的如下代碼:<?xmlversion="1.0"encoding="utf-8"?>ADT21開發(fā)版本以后,Android布局文件已不再需要該行代碼。不過,在很多情況下,可能還是會看到它。應(yīng)用activity的布局默認(rèn)定義了兩個組件(widget):RelativeLayout和TextView。組件是組成用戶界面的構(gòu)造模塊。組件可以顯示文字或圖像、與用戶交互,甚至是布置屏幕上的其他組件。按鈕、文本輸入控件和選擇框等都是組件。AndroidSDK內(nèi)置了多種組件,通過配置各種組件可獲得所需的用戶界面及行為。每一個組件是View類或其子類(如TextView或Button)的一個具體實例。圖1-8展示了代碼清單1-1中定義的RelativeLayout和TextView是如何在屏幕上顯示的。圖1-8顯示在屏幕上的默認(rèn)組件不過,圖1-8所示的默認(rèn)組件并不是我們需要的,QuizActivity的用戶界面需要下列五個組件:一個垂直LinearLayout組件;一個TextView組件;一個水平LinearLayout組件;兩個Button組件。圖1-9展示了以上組件是如何構(gòu)成QuizActivity活動用戶界面的。圖1-9布置并顯示在屏幕上的組件下面我們在activity_quiz.xml文件中定義這些組件。如代碼清單1-2所示,修改activity_quiz.xml文件。注意,需刪除的XML已打上刪除線,需添加的XML以粗體顯示。本書統(tǒng)一使用這樣的版式約定。代碼清單1-2在XML文件(activity_quiz.xml)中定義組件<RelativeLayoutxmlns:android="/apk/res/android"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".QuizActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world"/>
</RelativeLayout>
<LinearLayoutxmlns:android="/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/question_text"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/false_button"/>
</LinearLayout>
</LinearLayout>參照代碼清單直接輸入代碼,就算不理解這些代碼也沒關(guān)系,你會在后續(xù)的學(xué)習(xí)中弄明白的。需要特別注意的是,開發(fā)工具無法校驗布局XML內(nèi)容,請避免輸入或拼寫錯誤。根據(jù)所使用的工具版本不同,可能會得到三行以android:text開頭的代碼有誤。先暫時忽略它們,以后再去解決這一問題。將XML文件與圖1-9所示的用戶界面進(jìn)行對照,可以看出組件與XML元素一一對應(yīng)。元素的名稱就是組件的類型。各元素均有一組XML屬性。屬性可以看作是如何配置組件的指令。以層次等級視角來研究布局,有助于我們更方便地理解元素與屬性的運作方式。1.4.1視圖層級結(jié)構(gòu)組件包含在視圖對象的層級結(jié)構(gòu),即視圖層級結(jié)構(gòu)(viewhierarchy)中。圖1-10展示了代碼清單1-2所示XML布局對應(yīng)的視圖層級結(jié)構(gòu)。圖1-10布局中組件及屬性的層級結(jié)構(gòu)從布局的視圖層級結(jié)構(gòu)可以看到,其根元素是一個LinearLayout組件。作為根元素,LinearLayout組件必須指定AndroidXML資源文件的命名空間屬性為\h/apk/res/android。LinearLayout組件繼承自View子類的ViewGroup組件。ViewGroup組件是一個包含并配置其他組件的特殊組件。如需以一列或一排的樣式布置組件,使用LinearLayout組件就可以了。其他ViewGroup子類還包括FrameLayout、TableLayout和RelativeLayout。若某個組件包含在一個ViewGroup中,該組件與ViewGroup即構(gòu)成父子關(guān)系。根LinearLayout有兩個子組件:TextView和LinearLayout。作為子組件的LinearLayout本身還有兩個Button子組件。1.4.2組件屬性下面我們一起來看看配置組件的一些常用屬性。android:layout_width和android:layout_height屬性幾乎每類組件都需要android:layout_width和android:layout_height屬性。它們通常被設(shè)置為以下兩種屬性值之一。match_parent:視圖與其父視圖大小相同。wrap_content:視圖將根據(jù)其內(nèi)容自動調(diào)整大小。(以前還有一個fill_parent屬性值,等同于match_parent,目前已廢棄不用。)根LinearLayout組件的高度與寬度屬性值均為match_parent。LinearLayout雖然是根元素,但它也有父視圖(View)——Android提供該父視圖來容納應(yīng)用的整個視圖層級結(jié)構(gòu)。其他包含在界面布局中的組件,其高度與寬度屬性值均被設(shè)置為wrap_content。請參照圖1-9理解該屬性值定義尺寸大小的作用。TextView組件比其包含的文字內(nèi)容區(qū)域稍大一些,這主要是android:padding="24dp"屬性的作用。該屬性告訴組件在決定大小時,除內(nèi)容本身外,還需增加額外指定量的空間。這樣屏幕上顯示的問題與按鈕之間便會留有一定的空間,使整體顯得更為美觀。(不理解dp的意思?dp即density-independentpixel,指與設(shè)備無關(guān)的像素,第8章將介紹有關(guān)它的概念。)android:orientation屬性android:orientation屬性是兩個LinearLayout組件都具有的屬性,決定了二者的子組件是水平放置的還是垂直放置的。根LinearLayout是垂直的,子LinearLayout是水平的。LinearLayout子組件的定義順序決定著其在屏幕上顯示的順序。在豎直的LinearLayout中,第一個定義的子組件出現(xiàn)在屏幕的最上端。而在水平的LinearLayout中,第一個定義的子組件出現(xiàn)在屏幕的最左端。(如果設(shè)備語言為從右至左顯示,如Arabic或者Hebrew,第一個定義的子組件則出現(xiàn)在屏幕的最右端。)android:text屬性TextView與Button組件具有android:text屬性。該屬性指定組件顯示的文字內(nèi)容。請注意,android:text屬性值不是字符串字面值,而是對字符串資源(stringresources)的引用。字符串資源包含在一個獨立的名為strings的XML文件中,雖然可以硬編碼設(shè)置組件的文本屬性,如android:text="True",但這通常不是個好方法。將文字內(nèi)容放置在獨立的字符串資源XML文件中,然后引用它們才是好方法。在第15章中,我們將學(xué)習(xí)如何使用字符串資源輕松實現(xiàn)本地化。需要在activity_quiz.xml文件中引用的字符串資源目前還不存在?,F(xiàn)在我們來添加這些資源。1.4.3創(chuàng)建字符串資源每個項目都包含一個名為strings.xml的默認(rèn)字符串文件。在包瀏覽器中,找到res/values目錄,點擊小三角顯示目錄內(nèi)容,然后打開strings.xml文件。忽略圖形界面,在編輯區(qū)底部選擇strings.xml標(biāo)簽頁,切換到代碼界面。可以看到,項目模版已經(jīng)默認(rèn)添加了一些字符串資源。刪除不需要的hello_world部分,添加應(yīng)用布局需要的三個新的字符串,如代碼清單1-3所示。代碼清單1-3添加字符串資源(strings.xml)<?xmlversion="1.0"encoding="utf-8"?>
<resources>
<stringname="app_name">GeoQuiz</string>
<stringname="hello_world">Hello,world!</string>
<stringname="question_text">ConstantinopleisthelargestcityinTurkey.</string>
<stringname="true_button">True</string>
<stringname="false_button">False</string>
<stringname="menu_settings">Settings</string>
</resources>(項目已默認(rèn)配置好應(yīng)用菜單,請勿刪除menu_settings字符串設(shè)置,否則將導(dǎo)致與應(yīng)用菜單相關(guān)的其他文件發(fā)生版式錯誤。)現(xiàn)在,在GeoQuiz項目的任何XML文件中,只要引用到@string/false_button,應(yīng)用運行時,就會得到文本“False”。保存strings.xml文件。這時,activity_quiz.xml布局曾經(jīng)提示缺少字符串資源的信息應(yīng)該不會再出現(xiàn)了。(如仍有錯誤信息,那么檢查一下這兩個文件,確認(rèn)是否存在輸入或拼寫錯誤。)字符串文件默認(rèn)被命名為strings.xml,當(dāng)然也可以按個人喜好任意取名。一個項目也可以有多個字符串文件。只要這些文件都放置在res/values/目錄下,并且含有一個resources根元素,以及多個string子元素,字符串定義即可被應(yīng)用找到并得到正確使用。1.4.4預(yù)覽界面布局至此,應(yīng)用的界面布局已經(jīng)完成,現(xiàn)在我們使用圖形布局工具來進(jìn)行實時預(yù)覽。首先,確認(rèn)保存了所有相關(guān)文件并且無錯誤發(fā)生,然后回到activity_quiz.xml文件,在編輯區(qū)底部選擇圖形布局標(biāo)簽頁進(jìn)行界面布局預(yù)覽,如圖1-11所示。圖1-11在圖形布局工具中預(yù)覽界面布局(activity_quiz.xml)1.5從布局XML到視圖對象想知道activity_quiz.xml中的XML元素是如何轉(zhuǎn)換為視圖對象的嗎?答案就在于QuizActivity類。在創(chuàng)建GeoQuiz項目的同時,也創(chuàng)建了一個名為QuizActivity的Activity子類。QuizActivity類文件存放在項目的src目錄下。目錄src是項目全部Java源代碼的存放處。在包瀏覽器中,依次展開src目錄與com.bignerdranch.android.geoquiz包,顯示其中的內(nèi)容。然后打開QuizActivity.java文件,逐行查看其中的代碼,如代碼清單1-4所示。代碼清單1-4QuizActivity活動的默認(rèn)類文件(QuizActivity.java)packagecom.bignerdranch.android.geoquiz;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.Menu;
publicclassQuizActivityextendsActivity{
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
}
@Override
publicbooleanonCreateOptionsMenu(Menumenu){
getMenuInflater().inflate(R.menu.activity_quiz,menu);
returntrue;
}
}(如果無法看到全部類包導(dǎo)入語句,請單擊第一行導(dǎo)入語句左邊的⊕符號,從而顯示全部導(dǎo)入語句。)該Java類文件包含兩個Activity方法:onCreate(Bundle)和onCreateOptionsMenu(Menu)。暫不用理會onCreateOptionsMenu(Menu)方法,第16章會詳細(xì)介紹它。activity子類的實例創(chuàng)建后,onCreate(Bundle)方法將會被調(diào)用。activity創(chuàng)建后,它需要獲取并管理屬于自己的用戶界面。獲取activity的用戶界面,可調(diào)用以下Activity方法:publicvoidsetContentView(intlayoutResID)通過傳入布局的資源ID參數(shù),該方法生成指定布局的視圖并將其放置在屏幕上。布局視圖生成后,布局文件包含的組件也隨之以各自的屬性定義完成實例化。資源與資源ID布局是一種資源。資源是應(yīng)用非代碼形式的內(nèi)容,比如圖像文件、音頻文件以及XML文件等。項目的所有資源文件都存放在目錄res的子目錄下。通過包瀏覽器可以看到,布局activity_quiz.xml資源文件存放在res/layout/目錄下。包含字符串資源的strings文件存放在res/values/目錄下??墒褂?*資源**ID在代碼中獲取相應(yīng)的資源。activity_quiz.xml文件定義的布局資源ID為R.layout.activity_quiz。在包瀏覽器展開目錄gen,找到并打開R.java文件,即可看到GeoQuiz應(yīng)用當(dāng)前所有的資源ID。R.java文件在Android項目編譯過程中自動生成,遵照該文件頭部的警示,請不要嘗試修改該文件的內(nèi)容,如代碼清單1-5所示。代碼清單1-5GeoQuiz應(yīng)用當(dāng)前的資源ID(R.java)/*AUTO-GENERATEDFILE.DONOTMODIFY.
...
*/
packagecom.bignerdranch.android.geoquiz;
publicfinalclassR{
publicstaticfinalclassattr{
}
publicstaticfinalclassdrawable{
publicstaticfinalintic_launcher=0x7f020000;
}
publicstaticfinalclassid{
publicstaticfinalintmenu_settings=0x7f070003;
}
publicstaticfinalclasslayout{
publicstaticfinalintactivity_quiz=0x7f030000;
}
publicstaticfinalclassmenu{
publicstaticfinalintactivity_quiz=0x7f060000;
}
publicstaticfinalclassstring{
publicstaticfinalintapp_name=0x7f040000;
publicstaticfinalintfalse_button=0x7f040003;
publicstaticfinalintmenu_settings=0x7f040006;
publicstaticfinalintquestion_text=0x7f040001;
publicstaticfinalinttrue_button=0x7f040002;
}
...
}可以看到R.layout.activity_quiz即來自該文件。activity_quiz是R的內(nèi)部類layout里的一個整型常量名。這們定義的字符串同樣具有資源ID。目前為止,我們還未在代碼中引用過字符串,但如果需要,則應(yīng)該使用以下方法:setTitle(R.string.app_name);Android為整個布局文件以及各個字符串生成資源ID,但activity_quiz.xml布局文件中的組件除外,因為不是所有的組件都需要資源ID。在本章中,我們只用到兩個按鈕,因此只需為這兩個按鈕生成相應(yīng)的資源ID即可。要為組件生成資源ID,請在定義組件時為其添加上android:id屬性。在activity_quiz.xml文件中,分別為兩個按鈕添加上android:id屬性,如代碼清單1-6所示。代碼清單1-6為按鈕添加資源ID(activity_quiz.xml)<LinearLayoutxmlns:android="/apk/res/android"...>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/question_text"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/true_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button"/>
<Button
android:id="@+id/false_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/false_button"/>
</LinearLayout>
</LinearLayout>請注意android:id屬性值前面有一個+標(biāo)志,而android:text屬性值則沒有,這是因為我們將要創(chuàng)建資源ID,而對字符串資源只是做了引用。保存activity_quiz.xml文件,重新查看R.java文件,確認(rèn)R.id內(nèi)部類中生成了兩個新的資源ID,如代碼清單1-7所示。代碼清單1-7新的資源ID(R.java)publicfinalclassR{
...
publicstaticfinalclassid{
publicstaticfinalintfalse_button=0x7f070001;
publicstaticfinalintmenu_settings=0x7f070002;
publicstaticfinalinttrue_button=0x7f070000;
}
...1.6組件的實際應(yīng)用既然按鈕有了資源ID,就可以在QuizActivity中直接獲取它們。首先,在QuizActivity.java文件中增加兩個成員變量。在QuizActivity.java文件中輸入代碼清單1-8所示代碼。(請勿使用代碼自動補(bǔ)全功能。)代碼清單1-8添加成員變量(QuizActivity.java)publicclassQuizActivityextendsActivity{
privateButtonmTrueButton;
privateButtonmFalseButton;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
}
...
}文件保存后,可看到兩個錯誤提示。沒關(guān)系,這點錯誤馬上就可以搞定。請注意新增的兩個成員(實例)變量名稱的m前綴。該前綴是Android編程所遵循的命名約定,本書將始終遵循該約定。現(xiàn)在,請將鼠標(biāo)移至代碼左邊的錯誤提示處,可看到兩條同樣的錯誤:Buttoncannotberesolvedtoatype。該錯誤提示告訴我們需要在QuizActivity.java文件中導(dǎo)入android.widget.Button類包??稍谖募^部手動輸入以下代碼:importandroid.widget.Button;或者采用下面介紹的便捷方式自動導(dǎo)入。1.6.1類包組織導(dǎo)入使用類包組織導(dǎo)入,就是讓Eclipse依據(jù)代碼來決定應(yīng)該導(dǎo)入哪些Java或AndroidSDK類包。如果之前導(dǎo)入的類包不再需要了,Eclipse也會自動刪除它們。通過以下組合鍵命令,進(jìn)行類包組織導(dǎo)入:Command+Shift+O(Mac系統(tǒng));Ctrl+Shift+O(Windows和Linux系統(tǒng))。類包導(dǎo)入完成后,剛才的錯誤提示應(yīng)該就會消失了。(如果錯誤提示仍然存在,請檢查Java代碼以及XML文件,確認(rèn)是否存在輸入或拼寫錯誤。)接下來,我們來編碼使用按鈕組件,這需要以下兩個步驟:引用生成的視圖對象;為對象設(shè)置監(jiān)聽器,以響應(yīng)用戶操作。1.6.2引用組件在activity中,可通過以下Activity方法引用已生成的組件:publicViewfindViewById(intid)該方法接受組件的資源ID作為參數(shù),返回一個視圖對象。在QuizActivity.java文件中,使用按鈕的資源ID獲取生成的對象后,賦值給對應(yīng)的成員變量,如代碼清單1-9所示。注意,賦值前,必須先將返回的View轉(zhuǎn)型(cast)為Button。代碼清單1-9引用組件(QuizActivity.java)publicclassQuizActivityextendsActivity{
privateButtonmTrueButton;
privateButtonmFalseButton;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
mTrueButton=(Button)findViewById(R.id.true_button);
mFalseButton=(Button)findViewById(R.id.false_button);
}
...
}1.6.3設(shè)置監(jiān)聽器Android應(yīng)用屬于典型的事件驅(qū)動類型。不同于命令行或腳本程序,事件驅(qū)動型應(yīng)用啟動后,即開始等待行為事件的發(fā)生,如用戶單擊某個按鈕。(事件也可以由操作系統(tǒng)或其他應(yīng)用觸發(fā),但用戶觸發(fā)的事件更顯而易見。)應(yīng)用等待某個特定事件的發(fā)生,也可以說該應(yīng)用正在“監(jiān)聽”特定事件。為響應(yīng)某個事件而創(chuàng)建的對象叫做監(jiān)聽器(listener)。監(jiān)聽器是實現(xiàn)特定監(jiān)聽器接口的對象,用來監(jiān)聽某類事件的發(fā)生。無需自己編寫,AndroidSDK已經(jīng)為各種事件內(nèi)置開發(fā)了很多監(jiān)聽器接口。當(dāng)前應(yīng)用需要監(jiān)聽用戶的按鈕“單擊”事件,因此監(jiān)聽器需實現(xiàn)View.OnClickListener接口。首先處理True按鈕,在QuizActivity.java文件中,在變量賦值語句后輸入下列代碼到onCreate(...)方法內(nèi),如代碼清單1-10所示。代碼清單1-10為True按鈕設(shè)置監(jiān)聽器(QuizActivity.java)...
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
mTrueButton=(Button)findViewById(R.id.true_button);
mTrueButton.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
//Doesnothingyet,butsoon!
}
});
mFalseButton=(Button)findViewById(R.id.false_button);
}
}(如果遇到Viewcannotberesolvedtoatype的錯誤提示,請使用Mac的Command+Shift+O或Windows的Ctrl+Shift+O快捷鍵導(dǎo)入View類。)在代碼清單1-10中,我們設(shè)置了一個監(jiān)聽器。當(dāng)按鈕mTrueButton被點擊后,監(jiān)聽器會立即通知我們。setOnClickListener(OnClickListener)方法以監(jiān)聽器作為參數(shù)被調(diào)用。在特殊情況下,該方法以一個實現(xiàn)了OnClickListener接口的對象作為參數(shù)被調(diào)用。使用匿名內(nèi)部類SetOnClickListener(OnClickListener)方法傳入的監(jiān)聽器參數(shù)是一個匿名內(nèi)部類(anonymousinnerclass)實現(xiàn),語法看上去稍顯復(fù)雜,不過,只需記住最外層括號內(nèi)的全部實現(xiàn)代碼是作為整體參數(shù)傳入SetOnClickListener(OnClickListener)方法內(nèi)的即可。該傳入的參數(shù)就是新建的一個匿名內(nèi)部類的實現(xiàn)代碼。mTrueButton.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
//Doesnothingyet,butsoon!
}});本書所有的監(jiān)聽器都作為匿名內(nèi)部類來實現(xiàn)。這樣做的好處有二。其一,在大量代碼塊中,監(jiān)聽器方法的實現(xiàn)一目了然;其二,匿名內(nèi)部類的使用只出現(xiàn)在一個地方,因此可以減少一些命名類的使用。匿名內(nèi)部類實現(xiàn)了OnClickListener接口,因此它也必須實現(xiàn)該接口唯一的onClick(View)方法。onClick(View)方法的代碼暫時是一個空結(jié)構(gòu)。實現(xiàn)監(jiān)聽器接口需要實現(xiàn)onClick(View)方法,但具體如何實現(xiàn)由使用者決定,因此即使是空的實現(xiàn)方法,編譯器也可以編譯通過。(如果匿名內(nèi)部類、監(jiān)聽器、接口等概念你已忘得差不多了,現(xiàn)在就去復(fù)習(xí)復(fù)習(xí)Java語言的基礎(chǔ)知識,或者手邊放一本參考書備查。)參照代碼清單1-11為False按鈕設(shè)置類似的事件監(jiān)聽器。代碼清單1-11為False按鈕設(shè)置監(jiān)聽器(QuizActivity.java)...
mTrueButton.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
//Doesnothingyet,butsoon!
}
});
mFalseButton=(Button)findViewById(R.id.false_button);
mFalseButton.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
//Doesnothingyet,butsoon!
}
});
}創(chuàng)建提示消息現(xiàn)在讓我們把按鈕全副武裝起來,使其具有可操作性吧。接下來要實現(xiàn)的就是,分別單擊兩個按鈕,彈出我們稱為toast的提示消息。Android的toast指用來通知用戶的簡短彈出消息,但無需用戶輸入或做出任何操作。這里,我們要做的就是使用toast來告知用戶其答案正確與否,如圖1-12所示圖1-12toast反饋消息提示首先回到strings.xml文件,如代碼清單1-12所示,為toast添加消息顯示用的字符串資源。代碼清單1-12增加toast字符串(strings.xml)<?xmlversion="1.0"encoding="utf-8"?>
<resources>
<stringname="app_name">GeoQuiz</string>
<stringname="question_text">ConstantinopleisthelargestcityinTurkey.</string>
<stringname="true_button">True</string>
<stringname="false_button">False</string>
<stringname="correct_toast">Correct!</string>
<stringname="incorrect_toast">Incorrect!</string>
<stringname="menu_settings">Settings</string>
</resources>通過調(diào)用來自Toast類的以下方法,可創(chuàng)建一個toast:publicstaticToastmakeText(Contextcontext,intresId,intduration)該方法的Context參數(shù)通常是Activity的一個實例(Activity本身就是Context的子類)。第二個參數(shù)是toast待顯示字符串消息的資源ID。Toast類必須利用context才能找到并使用字符串的資源ID。第三個參數(shù)通常是兩個Toast常量中的一個,用來指定toast消息顯示的持續(xù)時間。創(chuàng)建Toast后,可通過調(diào)用Toast.show()方法使toast消息顯示在屏幕上。在QuizActivity代碼里,分別對兩個按鈕的監(jiān)聽器調(diào)用makeText(...)方法,如代碼清單1-13所示。在添加makeText(...)時,可利用Eclipse的代碼自動補(bǔ)全功能,讓代碼輸入工作更加輕松。代碼清單1-13創(chuàng)建提示消息(QuizActivity.java)...
mTrueButton.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
Toast.makeText(QuizActivity.this,
R.string.incorrect_toast,
Toast.LENGTH_SHORT).show();
}
});
mFalseButton.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
Toast.makeText(QuizActivity.this,
R.string.correct_toast,
Toast.LENGTH_SHORT).show();
}
});使用代碼自動補(bǔ)全代碼自動補(bǔ)全功能可以節(jié)約大量開發(fā)時間,越早掌握受益越多。參照代碼清單1-13,依次輸入代碼。當(dāng)輸入到Toast類后的點號時,Eclipse會彈出一個窗口,窗口內(nèi)顯示了建議使用的Toast類的常量與方法。為便于選擇所需的建議方法,可按Tab鍵移焦至自動補(bǔ)全彈出窗口上。(如果想忽略Eclipse的代碼自動補(bǔ)全功能,請不要按Tab鍵或使用鼠標(biāo)點擊彈出窗口,只管繼續(xù)輸入代碼直至完成。)在列表建議清單里,選擇makeText(Context,int,int)方法,代碼自動補(bǔ)全功能會自動添加完成方法調(diào)用,包括參數(shù)的占位符值。第一個占位符號默認(rèn)加亮,直接輸入實際參數(shù)值QuizActivity.this。然后按Tab鍵轉(zhuǎn)至下一個占位符,輸入實際參數(shù)值,依次類推,直至參照代碼清單1-13完成全部參數(shù)的輸入。在makeText(...)里,傳入QuizActivity實例作為Context的參數(shù)值。注意此處應(yīng)輸入的參數(shù)是QuizActivit.this,不要想當(dāng)然地直接輸入this作為參數(shù)。因為匿名類的使用,這里的this指的是監(jiān)聽器View.OnClickListener。使用代碼自動補(bǔ)全功能,Eclipse會自動導(dǎo)入所需的類。因此,無需使用類包組織導(dǎo)入來導(dǎo)入Toast類了。1.7使用模擬器運行應(yīng)用要運行Android應(yīng)用,需使用硬件設(shè)備或者虛擬設(shè)備(virtualdevice)。包含在開發(fā)工具中的Android設(shè)備模擬器可提供多種虛擬設(shè)備。要想創(chuàng)建Android虛擬設(shè)備(AVD),在Eclipse中,選擇Window→AndroidVirtualDeviceManager菜單項,當(dāng)AVD管理器窗口彈出時,點擊窗口右邊的New…按鈕。在隨后彈出的對話框中,可以看到有很多配置虛擬設(shè)備的選項。對于首個虛擬設(shè)備,我們選擇模擬運行GoogleAPIs-APILevel17的GalaxyNexus設(shè)備,如圖1-13所示。注意,如果使用的是Windows系統(tǒng),需要將內(nèi)存選項值從1024改為512,這樣虛擬設(shè)備才能正常運行。配置完成后,點擊OK確認(rèn)。圖1-13創(chuàng)建新的AVDAVD創(chuàng)建成功后,我們用它運行GeoQuiz應(yīng)用。在包瀏覽器中,右擊GeoQuiz項目文件夾。在彈出的右鍵菜單中,選擇RunAs→AndroidApplication菜單項。Eclipse會自動找到新建的虛擬設(shè)備,安裝應(yīng)用包(APK),然后啟動并運行應(yīng)用。在此過程中,如果Eclipse詢問是否使用LogCat自動監(jiān)控,選擇“Yes”。啟動虛擬機(jī)可能比較耗時,請耐心等待。設(shè)備啟動完成,應(yīng)用運行后,就可以在應(yīng)用界面點擊按鈕,讓toast告訴我們答案。(注意,如果應(yīng)用啟動運行后,我們湊巧不在電腦旁,回來時,就可能需要解鎖AVD。如同一臺真實設(shè)備,AVD閑置一定時間會自動鎖上。)假如GeoQuiz應(yīng)用啟動時或在我們點擊按鈕時發(fā)生崩潰,LogCat會出現(xiàn)在Eclipse工作區(qū)的底部。查看日志,可看到搶眼的紅色異常信息,如圖1-14所示。日志中的Text列可看到異常的名字以及發(fā)生問題的具體位置。圖1-14第21行代碼發(fā)生了NullPointerException異常將輸入的代碼與書中的代碼作一下比較,找出錯誤并修改后,再嘗試重新運行應(yīng)用。建議保持模擬器一直運行,這樣就不必在反復(fù)運行調(diào)試應(yīng)用時,痛苦地等待AVD啟動了。單擊回退按鈕(即AVD模擬器上的U型箭頭按鈕)可以停止應(yīng)用。需要調(diào)試變更時,再通過Eclipse重新運行應(yīng)用。雖然模擬器非常有用,但在真實設(shè)備上測試應(yīng)用能夠獲得更準(zhǔn)確的結(jié)果。在第2章中,我們將在真實硬件設(shè)備上運行GeoQuiz應(yīng)用,并且為GeoQuiz應(yīng)用添加更多地理知識問題,以供用戶回答。1.8Android編譯過程學(xué)習(xí)到這里,你可能對Android編譯過程是如何工作的充滿疑惑。我們已經(jīng)知道在項目文件發(fā)生變化時,無需使用命令行工具,Eclipse便會自動進(jìn)行編譯。在整個編譯過程中,Android開發(fā)工具將資源文件、代碼以及AndroidManifest.xml文件(包含應(yīng)用的元數(shù)據(jù))編譯生成.apk文件,如圖1-15所示。為了讓.apk應(yīng)用能夠在模擬器上運行,.apk文件必須以debugkey簽名。(分發(fā).apk應(yīng)用給用戶時,應(yīng)用必須以releasekey簽名。如需了解更多有關(guān)編譯過程的信息,可參考Android開發(fā)文檔\h/tools/publishing/preparing.html。)圖1-15編譯GeoQuiz應(yīng)用那么,應(yīng)用的activity_quiz.xml布局文件的內(nèi)容該如何轉(zhuǎn)變?yōu)閂iew對象呢?作為編譯過程的一部分,aapt(AndroidAssetPackagingTool)將布局文件資源編譯壓縮緊湊后,打包到.apk文件中。當(dāng)QuizActivity類的onCreate(...)方法調(diào)用setContentView(...)方法時,QuizActivity使用LayoutInflater類實例化定義在布局文件中的每一個View對象,如圖1-16所示。圖1-16activity_quiz.xml中的視圖實例化(除了在XML文件中定義視圖的方式外,也可以在activity里使用代碼的方式創(chuàng)建視圖類。但應(yīng)用展現(xiàn)層與邏輯層分離有很多好處,其中最主要的優(yōu)點是可以利用SDK內(nèi)置的設(shè)備配置改變,有關(guān)這一點將在第3章中詳細(xì)講解。)有關(guān)XML不同屬性的工作原理以及視圖是如何顯示在屏幕上的等更多信息,請參見第8章。Android編譯工具截至目前,我們所看到的項目編譯都是在Eclipse里執(zhí)行的。編譯功能已整合到正在使用的ADT開發(fā)插件中,插件調(diào)用了aapt等Android的標(biāo)準(zhǔn)編譯工具,但編譯過程本身是由Eclipse來管理的。有時,出于種種原因,可能需要脫離Eclipse進(jìn)行代碼編譯。最簡單的方法是使用命令行編譯工具。當(dāng)前最流行的兩大工具是maven和ant。使用ant的人相對較少,但使用起來相對比較容易。使用ant前應(yīng)完成如下準(zhǔn)備工作:確保ant已安裝并可以正常運行;確保AndroidSDK的tools/和platform-tools/目錄包含在可執(zhí)行文件的搜索路徑中?,F(xiàn)在切換到項目目錄并執(zhí)行以下命令:$androidupdateproject-p.Eclipse項目生成器模板不包含ant可用的build.xml。以上命令將生成build.xml文件。該命令只需要運行這一次即可。接下來就可以編譯項目了。如果需要編譯并簽名為debug的.apk,請在同一目錄下執(zhí)行如下命令:$antdebug該命令執(zhí)行后即開始進(jìn)行實際的項目編譯,編譯完成后在bin/your-project-name-debug.apk目錄下生成相應(yīng)的.apk文件。再通過以下安裝命令安裝.apk文件:$adbinstallbin/your-project-name-debug.apk以上命令將把a(bǔ)pk應(yīng)用安裝到當(dāng)前連接的設(shè)備上,但不會運行它。要運行應(yīng)用,需要在設(shè)備上手動啟動安裝的應(yīng)用。第2章Android與MVC設(shè)計模式本章我們將對GeoQuiz應(yīng)用進(jìn)行功能升級,讓應(yīng)用能夠提供更多的地理知識測試題目,如圖2-1所示。圖2-1更多測試題目為實現(xiàn)目標(biāo),需要為GeoQuiz項目新增一個TrueFalse類。該類的一個實例用來封裝代表一道題目。然后再創(chuàng)建一個TrueFalse數(shù)組對象交由QuizActivity管理。2.1創(chuàng)建新類在包瀏覽器中,右鍵單擊com.bignerdranch.android.geoquiz類包,選擇New→Class菜單項,彈出圖2-2所示的對話框。類名處填入TrueFalse,保持默認(rèn)的超類java.lang.Object不變,然后單擊Finish按鈕。圖2-2創(chuàng)建TrueFalse類在TrueFalse.java中,新增兩個成員變量和一個構(gòu)造方法,如代碼清單2-1所示。代碼清單2-1TrueFalse類中的新增代碼(TrueFalse.java)publicclassTrueFalse{
privateintmQuestion;
privatebooleanmTrueQuestion;
publicTrueFalse(intquestion,booleantrueQuestion){
mQuestion=question;
mTrueQuestion=trueQuestion;
}
}mQuestion為什么是int類型的,而不是String類型的呢?變量mQuestion用來保存地理知識問題字符串的資源ID。資源ID總是int類型,所以這里設(shè)置它為int而不是String類型。變量mTrueQuestion用來確定答案正確與否,需要使用到的問題字符串資源稍后會處理。新增的兩個變量需要getter與setter方法。為避免手工輸入,可設(shè)置由Eclipse自動生成getter與setter方法。生成getter與setter方法首先,配置Eclipse識別成員變量的m前綴,并且對于boolean類型的成員變量使用is而不是get前綴。打開Eclipse首選項對話框(Mac用戶選擇Eclipse菜單,Windows用戶選擇Windows→Preferences菜單)。在Java選項下選擇CodeStyle。在Conventionsforvariablenames:表中,選擇Fields行,如圖2-3所示。單擊右邊的Edit按鈕,增加m作為fields的前綴。然后增加s作為StaticFields的前綴。(GeoQuiz項目不會用到s前綴,但在之后的項目中會用到。)確認(rèn)Use‘is’prefixforgettersthatreturnboolean選擇框被勾選后,單擊OK按鈕,如圖2-3所示。圖2-3設(shè)置Java代碼風(fēng)格首選項剛才設(shè)置的前綴有何作用?現(xiàn)在,當(dāng)要求Eclipse為mQuestion生成getter方法時,它生成的是getQuestion()而不是getMQuestion()方法;而在為mTrueQuestion生成getter方法時,生成的則是isTrueQuestion()而不是isMTrueQuestion()方法?;氐絋rueFalse.java中,右擊構(gòu)造方法后方區(qū)域,選擇Source→GenerateGettersAndSetters...菜單項。點擊SelectAll按鈕,為每個變量都生成getter與setter方法。單擊OK按鈕,Eclipse隨即生成了這四個getter與setter方法的代碼,如代碼清單2-2所示。代碼清單2-2生成getter與setter方法(TrueFalse.java)publicclassTrueFalse{
privateintmQuestion;
privatebooleanmTrueQuestion;
publicTrueFalse(intquestion,booleantrueQuestion){
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 海鮮購銷合同范本模板示例
- 借款合同協(xié)議格式
- 技術(shù)開發(fā)與服務(wù)協(xié)議
- 玻璃原片采購交易價目表
- 借款合同中的抵押條款
- 重新簽訂的合同協(xié)議
- 農(nóng)產(chǎn)品選購合同格式
- 展覽活動承包合同
- 文化傳播公司內(nèi)容創(chuàng)意與市場推廣策略方案設(shè)計方
- 智慧城市管理
- 110kV升壓站構(gòu)支架組立施工方案
- 何以中國:公元前的中原圖景
- 【中藥貯藏與養(yǎng)護(hù)問題及解決對策4000字(論文)】
- 自然環(huán)境對聚落的影響
- 2023-2024學(xué)年天津市部分地區(qū)六年級數(shù)學(xué)第一學(xué)期期末綜合測試試題含答案
- 河南省洛陽市偃師區(qū)2023-2024學(xué)年四年級數(shù)學(xué)第一學(xué)期期末經(jīng)典模擬試題含答案
- 小學(xué)生預(yù)防性侵講稿
- 人工智能算法貝葉斯算法
- 外墻外保溫監(jiān)理實施細(xì)則
- 剪映使用課件s
- B2B電子商務(wù)網(wǎng)站調(diào)研報告
評論
0/150
提交評論