抽絲剝繭之探索Jetpack的最佳實踐-sunflower

2020-10-25 10:02:23


前言

sunflower是運用了Jetpack元件,而開發出的一個app,語言採用的是kotlin。本文要求大家應該對Jetpack元件,及kotlin語法有一定的瞭解。
Android Jetpack元件推薦的使用專案架構:
 注意所有的參照都是單向的,尤其注意viewModel會持有repository的參照。
 而對資料的操作(通過Dao的增刪查改)和網路請求都是在repository中完成的

在這裡插入圖片描述
sunflower專案的地址為:https://github.com/android/sunflower


專案的整體流程

該專案介面主要分為三個部分:

  1. gardenPlanting部分 -> 我的花園介面
  2. plantList部分 -> 植物列表的介面
  3. plantDetail部分 -> 植物的詳情介面

注意:沒有考慮gallery部分,因為gallery部分還需要申請API的金鑰。

從資料庫層面進行分析

分為garden_plantingsplants兩個資料表
有兩個data實體類,GardenPlantingPlant
Plant資料類對應plants表,GardenPlanting資料類對應garden_plants
plants表:儲存了所有植物的資訊
這裡資料的獲取並不是來源於網路,而是來自於事先已經建立好了的assets目錄下的json陣列,並在資料庫建立時,通過WorkManger傳送這個請求,把所有Plant的資訊insert到plants表中。

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述garden_plantings表:記錄了plant的名字,種下日期,最後澆水的時間。
當你選擇你要新增的植物(在植物的detail介面),就會根據plantId屬性insertgarden_plantings表中。
在這裡插入圖片描述
在這裡插入圖片描述
此外,還有一個資料類PlantAndGardenPlantings

表示兩個表之間的對映關係,一個Plant,對應多個GardenPlanting,兩個表通過Plant的id與GardenPlanting的plant_id來聯絡,通過observe方法,我的花園介面就會同步重新整理。
為什麼存在這個表,因為在我的花園介面,不僅要顯示plants表中的資訊,還要顯示garden_plants表的資訊。

在這裡插入圖片描述
在這裡插入圖片描述

小結:
我的花園介面即GardenFragment對應的倉庫是GardenPlantingRepository,倉庫中的Dao是gardenPlantingDao,填充介面資料的實體類是PlantAndGardenPlantings而不是GardenPlanting
植物列表即PlantListFragment對應的倉庫是PlantRepository,Dao層是PlantDao,填充介面資料所用到的類是Plant
植物的詳情介面即PlantDetailFragment對應的倉庫有PlantRepositoryGardenPlantingRepository,前者用於填充介面資料,後者則用於記錄植物的新增及刪除操作

從執行流程進行分析

在這裡插入圖片描述

  1. 找到程式的入口
        <activity
            android:name=".GardenActivity"
            android:theme="@style/Theme.Sunflower.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
  1. 進入到我的花園介面
    如果執行了sunflower這個專案,app一開啟就會進入到這個介面,那麼它是怎麼實現的呢?
    在這裡插入圖片描述
    此處會用到Navigation元件,GardenActivity對應的xml中有一個控制元件,它有一個屬性app:navGraphapp:navGraph: 屬性賦值的是 nagation檔案(類似是一個的導航圖),用來管理fragment及跳轉

在這裡插入圖片描述

<fragment
    android:id="@+id/nav_host"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/nav_garden"/>

nav_garden的視覺化介面如下
注意箭頭(action)代表的就是跳轉方向,可能還會攜帶引數傳遞
,這個可以用外掛實現。
比如說:跳轉到plant的詳情介面,肯定會需要plantId屬性(來源於plants表),因為必須要知道是哪個plant的detail介面開啟了。
在這裡插入圖片描述
所以此時就來到了與view_pager_fragment所對應的HomeViewPagerFragment,它大體採用的就是tablayout + viewpager2,有兩個頁面,GardenFragmentPlantListFragment,預設選中的就是GardenFragment頁面,即我的花園介面

  1. fragment之間的跳轉

第一次啟動這個app,GardenFragment介面沒有plant,點選add plant按鈕,就會跳轉到PlantListFragment

private fun navigateToPlantListPage() {
    requireActivity().findViewById<ViewPager2>(R.id.view_pager).currentItem =
        PLANT_LIST_PAGE_INDEX
}

在這裡插入圖片描述

PlantListFragment介面點選某植物會進入PlantDetailFragment,如果某植物已經新增到我的花園中,就不會顯示新增植物的button
在這裡插入圖片描述
在這裡插入圖片描述

在這裡插入圖片描述
相同地,在GardenFragment也能跳轉到PlantDetailFragment