標籤:注釋 draw 回調機制 load ica 編程 input nbsp 靜態
MVC 模式的最基本概念是分層設計,把我們的代碼基於 View(視圖)、Model(模型)、Controller(控制器)進行分類封裝,這樣做的目的是為了清晰結構,使代碼更易維護和擴充。
在上一篇文章中,我們完成了計算機的介面還原,但嚴格來說並不是真正的 View 類,因為它還沒反映視圖的邏輯。在這次文章中,我們將編寫計算機程式的 View 部分,Let’s Go!
(注意:這次在代碼的注釋中寫了較多的點,所以可以多看注釋部分)
一,初識 Activity
Activity(活動)作為 Android 四大組件之一,相當於應用中的整個介面,用前端的角度看,就像一個 web 頁。而 Activity 的實質是什麼呢?這次先簡要描述,從 Google 大神中可知,Activity 起始繼承於 Context 類,來看看它們的描述關鍵詞:
android.content.Context
Interface to global information about an application environment … It allows access to application-specific resources and classes, as well as up-calls for application-level operation …
原來 Context 被定義為關於應用情境(上下文)的抽象類別,具有訪問應用程式層面資源和類的許可權,並封裝了一些應用層級的方法。
android.app.Activity
An activity is a single, focused thing that the user can do … interact with the user … takes care of creating a window (full-screen windows or floating windows) for place UI …
Activity 被定義為與使用者互動(事件),負責建立載入視圖的視窗等功能的功能類。可以說因 Context,使 Activity 具有強大的功能。
在開始編寫前,先介紹一個重要的 Java 檔案 - R.java,在前面介紹過,gen 目錄會自動產生一些系統需要的檔案,開啟 R.java:
R 類通過 attr,color,drawable,id,layout 等靜態內部類,記錄了所有標識。
(注意:R類的標識會自動產生,不用去修改)
二,在 onCreate 中編寫我們的程式
Activity 有個明顯的特點,就是有生命週期。可以想象一下平時應用的使用過程,從一個介面滑入至另一介面,又從當前介面返回,伴隨的就是 Activity 周期的不同階段。開啟 Calculator 項目的 MainActivity.java 檔案:
在前端編程中,最重要的是擷取操作對象(dom)。在 Android 中也如此,主要通過 id 標識擷取操作對象。我們首先給activity_main.xml 中的 TextView 和 Button 加上以下 id 標識:
(@+id/{name} 的意思是在 R 類中增加為 {name} 的 id 標識)
- TextView:@+id/ResultOutput
- Button 數字 0 ~ 9:@+id/Operand0 ~ @+id/Operand9
- Button 除號:@+id/Operate0
- Button 乘號:@+id/Operate1
- Button 減號:@+id/Operate2
- Button 加號:@+id/Operate3
- Button 等號:@+id/Operate4
- Button 清除:@+id/Operate5
,請務必為元素加上正確的 id。
在 Android 中,主要通過 findViewById() 方法擷取操作對象,如TextView的擷取:
在前端編程中,我們可以通過 getElementsByTagName() 方法擷取一系列操作元素,但在 Android 中卻沒那麼幸運了,沒有這種方法。那有什麼快捷點的方式不?答案是肯定的。我們知道 findViewById() 傳入的是一個 int 類型的引用值,那麼可否通過迴圈的方式找出這些引用值,然後直接擷取呢?我們把 Button 元素分為兩組,運算元的 id 以 Operand0 ~ 9 命名。而其餘為運算子,則以 Operate0 ~ 5 命名(如上面提示的)。這樣我們則可以:
這樣,通過一個 TextView 和兩個數組,我們就把需要的操作元素全部收集好了。
三,分離及定義 View 類的介面
從上面的代碼看,一切似乎都很美好,但這種面向過程的思考方式是導致代碼迅速膨脹,難以維護的原因之一。按 MVC 的設計思想,上面編寫的代碼應屬於視圖部分的邏輯,更好的辦法應該封裝在視圖內,實現細節不被其它類所知。我們現在遵循這一思想從新組織一下代碼:
(注意:這裡只樸素地用 MVC 思想表達意圖,至於劃分及編寫的合理性就不探究了)
計算機將由兩個 View 類組成,一個是用於顯示結果的 CaOutputView 類,一個是用於使用者輸入的 CaInputView 類。首先建立存放 View 類的包,通過包區分不同類型檔案。
然後我們建立這兩個 View 類:
接著,我們開啟 CaInputView.java 檔案。好了,現在我們來思考一個問題,CaInputView 負責與使用者的互動,自然會知道使用者按了什麼按鈕,但怎樣通知 Activity 使用者的行為呢? 這個就是我們準備要接觸的回調機制的概念。
就好比,CaInputView 對 Activity 說:你把“連絡方式”留我,使用者輸入了我就通知你。而“連絡方式”有多種實現的方式。這次就通過委託的方式實現,相當於 iOS 中的代理(delegate)的概念:
四,編寫 View 類
現在我們繼續編寫 CaInputView類,把原先 Activity 類的代碼邏輯歸入 CaInputView 類:
繼續編寫 CaOutputView 類,CaOutputView 類比較簡單,只用於顯示:
五,在 Activity 中使用 View 類
兩個 View 已經建立完畢,現在可以嘗試在 Activity 中使用了:
提示錯誤,是因為執行個體化了 CaInputView,卻沒有實現介面,所以提示 MainActivity 應該實現 CaInputView 聲明的介面:
實現 CaInputView 聲明的介面後仍然會報錯,因為沒實現介面聲明的方法,選擇“Add unimplemented methods”則自動添加了方法,如:
最後當 CaInputView 與使用者發生互動時,我們“通知” Activity,而 Activity 則調用 CaOutputView 將結果顯示出來,MainActivity 類的最終代碼如:
運行程式,點擊每個按鈕,看是否顯示正確的值:
通過分層設計,MainActivity 中的代碼變得簡潔很多,它只需知道如何使用 View 類則可,使它可以專註於自己的責任部分。
六,總結
這次說了的點比較多,主要有:
- MVC 的設計概念
- 兩種方式擷取操作對象
- Java 的類型及轉型相關概念
- 回調機制及介面
- 如何使用 View 類
如果對這些點還不清晰,可以再細看注釋部分,或者留言給我,我會儘快回覆。另外我也會盡量加快更新進度,下周將利用遞迴函式編寫我們的 Model 類,敬請期待。
Android入門:MVC模式(中)