專案:Forage 應用程式

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

1. 事前準備

本程式碼研究室將介紹名為「Forage」的新應用程式,需由您自行建構。本程式碼研究室可逐步帶你瞭解完成「Forage」應用程式專案的步驟,包括在 Android Studio 中進行專案設定及測試。

必要條件

  • 此專案適用於已完成 Android Basics in Kotlin 課程第 5 單元的學生。

建構項目

  • 實作實體、DAO、ViewModel 和資料庫類別,以便透過 Room 在應用程式中加入持續性機制。

軟硬體需求

  • 已安裝 Android Studio 的電腦。

2. 已完成應用程式總覽

完成後的 Forage 應用程式可讓使用者追蹤他們在自然界中覓得的項目,例如食物。在使用 Room 的工作階段之間會保留此資料。您將運用所掌握的「Room」知識,以及對在資料庫執行讀取、寫入、更新及刪除作業的瞭解,在 Forage 應用程式中實現持續性。下文說明完成後的應用程式及其功能。

應用程式初次啟動時,使用者會看到空白畫面,其中包含顯示覓得項目的回收器檢視畫面,還有右下角的一個浮動的按鈕,可用來新增項目。

3edd87e63c387d88.png

新增新項目時,使用者可以指定名稱、找到項目的地點,以及額外附註。你也可以有核取方塊,以指定食品是否屬於當季。

6c0c739569bb3b4f.png

新增的項目將顯示在第一個畫面的回收器檢視畫面中。

bcc75e60b70320e8.png

輕觸某個項目就會開啟詳細資料畫面,並顯示名稱、地點和附註。

5096995a4921dcac.png

浮動式按鈕也會從加號符號變更為編輯圖示 輕觸此按鈕就可開啟畫面,讓您可以編輯名稱、地點、附註和「當季」核取方塊。輕觸刪除按鈕就可從資料庫中移除項目。

f8c708fed3dede1a.png

雖然已導入此應用程式的使用者介面部分,但您的工作是先運用掌握的「Room」知識來實現持續性,讓應用程式能夠讀取、寫入、更新及刪除資料庫中的項目。

3. 開始操作

下載專案程式碼

請注意,資料夾名稱是 android-basics-kotlin-forage-app。在 Android Studio 中開啟專案時,請選取這個資料夾。

如要取得這個程式碼研究室的程式碼,並在 Android Studio 中開啟,請按照下列步驟操作:

取得程式碼

  1. 按一下所提供的網址。系統會在瀏覽器中開啟專案的 GitHub 頁面。
  2. 在專案的 GitHub 頁面中,按一下「Code」(程式碼) 按鈕開啟對話方塊。

5b0a76c50478a73f.png

  1. 在對話方塊中,按一下「Download ZIP」(下載 ZIP 檔案) 按鈕,將專案儲存到電腦。等待下載作業完成。
  2. 在電腦中找到該檔案 (可能位於「下載」資料夾中)。
  3. 按兩下 ZIP 檔案,將檔案解壓縮。這項操作會建立含有專案檔案的新資料夾。

在 Android Studio 中開啟專案

  1. 啟動 Android Studio。
  2. 在「Welcome to Android Studio」(歡迎使用 Android Studio) 視窗中,按一下「Open an existing Android Studio project」(開啟現有的 Android Studio 專案)

36cc44fcf0f89a1d.png

注意:如果 Android Studio 已開啟,請改為依序選取「File」(檔案) >「New」(新增) >「Import Project」(匯入專案) 選單選項。

21f3eec988dcfbe9.png

  1. 在「Import Project」(匯入專案) 對話方塊中,瀏覽至解壓縮專案資料夾所在的位置 (可能位於「Downloads」(下載) 資料夾中)。
  2. 按兩下該專案資料夾。
  3. 等待 Android Studio 開啟專案。
  4. 按一下「Run」(執行) 按鈕 11c34fc5e516fb1c.png 即可建構並執行應用程式。請確認應用程式的建構符合預期。
  5. 在「Project」(專案) 工具視窗中瀏覽專案檔案,查看應用程式的設定方式。

4. 設定專案以使用 Room

定義 Forageable 實體

專案已有 Forageable 類別,可定義應用程式的資料 (model.Forageable.kt)。此類別有多個屬性:idnameaddressinSeasonnotes

data class Forageable(
   val id: Long = 0,
   val name: String,
   val address: String,
   val inSeason: Boolean,
   val notes: String?
)

不過,若要使用此類別儲存持續性資料,就必須將類別轉換為 Room 實體。

  1. 使用這個表格名稱為 "forageable_database"@Entity 為類別加上註解。
  2. id 屬性設定為主鍵。主鍵應由系統自動產生。
  3. inSeason 屬性的欄名稱設定為 "in_season"

實作 DAO

ForageableDao (data.ForageableDao.kt) 可用來定義從資料庫讀取及寫入資料庫的方法,就如同您的猜像。由於 DAO 只是您定義的介面,因此無需撰寫任何程式碼即可導入這些方法。您應該改用 Room 註解,視需要指定 SQL 查詢。

ForageableDao 介面中,您必須新增五個方法。

  1. getForageables() 方法會對於資料庫中所有資料列傳回 Flow<List<Forageable>>
  2. getForageable(id: Long) 方法會傳回符合指定 idFlow<Forageable>
  3. insert(forageable: Forageable) 方法會將新的 Forageable 插入至資料庫中。
  4. update(forageable: Forageable) 方法會採用現有 Forageable 作為參數,並據此更新資料列。
  5. delete(forageable: Forageable) 方法會採用 Forageable 作為參數,然後從資料庫中將其刪除。

導入檢視模型

ForageableViewModel (ui.viewmodel.ForageableViewModel.kt) 已部分導入,但您必須新增可存取 DAO 方法的功能,才能實際讀取及寫入資料。請按照下列步驟導入 ForageableViewModel

  1. 應將 ForageableDao 執行個體作為類別建構函式中的參數傳遞。
  2. 建立 LiveData<List<Forageable>> 型別的變數,並使用 DAO 取得完整的 Forageable 實體清單,並將結果轉換為 LiveData
  3. 建立採用 (Long 型別) ID 作為參數的方法,並傳回 DAO 呼叫 getForageable() 方法的 LiveData<Forageable>,然後將結果轉換為 LiveData
  4. addForageable() 方法中,使用 viewModelScope 啟動協同程式,並使用 DAO 將 Forageable 執行個體插入至資料庫中。
  5. updateForageable() 方法中,使用 DAO 更新 Forageable 實體。
  6. deleteForageable() 方法中,使用 DAO 更新 Forageable 實體。
  7. 建立可使用 ForageableDao 建構函式參數 建立 ForageableViewModel 執行個體的 ViewModelFactory

導入資料庫類別

ForageDatabase (data.ForageDatabase.kt) 類別實際上是將實體和 DAO 公開給 Room。按照說明導入 ForageDatabase 類別。

  1. 實體:Forageable
  2. 版本:1
  3. exportSchema:false
  4. ForageDatabase 類別中,加入能夠傳回 ForageableDao 的抽象函式
  5. ForageDatabase 類別中,用名為 INSTANCE 的私人變數和傳回 ForageDatabase 單例模式的 getDatabase() 函式定義夥伴模式物件。
  1. BaseApplication 類別中,建立使用延遲初始化功能傳回 ForageDatabase 執行個體的 database 屬性。

5. 保留及讀取片段中的資料

設定實體、DAO、檢視模型,以及定義要在 Room 公開的資料庫類別後,您只需要修改 Fragments,以便存取檢視模型。您必須在三個檔案中進行變更,各檔案用於應用程式中的各畫面。

Forageable 清單

Forageable 清單畫面只需要兩個項目:檢視畫面模型的參照,以及對完整 Forageable 清單的存取權限。在 ui.ForageableListFragment.kt 中執行以下工作。

  1. 類別中已有 viewModel 屬性。但不使用您在上一個步驟中定義的工廠。您必須先重構此宣告,才能使用 ForageableViewModelFactory
private val viewModel: ForageableViewModel by activityViewModels {
   ForageableViewModelFactory(
       (activity?.application as BaseApplication).database.foragableDao()
   )
}
  1. 然後,從 onViewCreated() 觀測 viewModelallForageables 屬性,並視需要在轉接程式上呼叫 submitList() 來填入清單。

Forageable 詳細資料畫面

您針對 ui/ForageableDetailFragment.kt 中的詳細資料清單執行的動作幾乎相同。

  1. 轉換 viewModel 屬性以正確初始化 ForageableViewModelFactory
  2. onViewCreated() 中,在檢視模型上呼叫 getForageable(),並傳入 id 以取得 Forageable 實體。觀測動態資料並將結果設定為 forageable 屬性,然後呼叫 bindForageable() 來更新使用者介面。

新增及編輯 Forageable 畫面

最後,您需要在 ui.AddForageableFragment.kt 中進行類似動作。請注意,此畫面也會負責更新及刪除實體。不過,已從檢視模型的正確位置呼叫這些方法。您只需在此檔案中進行兩項變更即可。

  1. 再次重構 viewModel 屬性以使用 ForageableViewModelFactory
  2. 設定刪除按鈕的瀏覽權限之前,在 onViewCreated() 的 if 陳述式區塊中,呼叫檢視畫面模型的 getForageable(),並傳入 id,然後將結果設定為 forageable 屬性。

這就是您需要在片段中執行的所有動作。您現在可以執行應用程式,藉此查看動作中的所有持續性功能。

6. 測試指示

執行測試

如要執行測試,請執行下列其中一項動作:

如果是單一測試案例,請開啟測試案例類別 PersistenceInstrumentationTests.kt,然後按一下類別宣告左側的綠色箭頭。然後,您可以從選單中選取「Run」(執行) 選項。這麼做將會執行測試案例中的所有測試。

3e640ec727599a6d.png

您通常只需要執行一項測試,例如只有一個測試失敗,其他測試都通過。執行單一測試的做法,與執行整個測試案例一樣。使用綠色箭頭並選取「Run」(執行) 選項。

8647a76419540499.png

如果您有多個測試案例,也可以執行整個測試套裝組合。就像執行應用程式一樣,你可以在「Run」(執行) 選單中找到這個選項。

7a925c5e196725bb.png

請注意,Android Studio 會預設為您所執行的最後一個目標 (應用程式、測試目標等),如果選單仍顯示「Run」(執行) >「Run ‘app'」(執行「應用程式」),您可以依序選取「Run」(執行) >「Run」(執行) 以執行測試目標。

90d3ec5ca5928b2a.png

然後從彈出式選單中選擇測試目標。

3b1a7d82a55b5f13.png