AstroPhotons的設計

這是寫給以後的自己看的記錄文。以便日後更新App。

- 程式架構

如網頁標題,這是給Android的App。採用Jetpack Compose的部件(components)來設計介面,循著MVVM (Model-View-ViewModel)的標準,焦點分離(Separation of Concern)的原則來規劃架構。最底層是與介面無關的Repository: Database Repository (Room), Network Repository(Retrofit2), Status of Network Repository (System)。所有的Repository都以資料流(Flow)的方式把資料的更新提交給ViewModel,再由ViewModel更新介面的狀態,確保使用者看到的都是最即時的資訊。

- 資料流

ViewModel初使化時首先判斷資料庫(Room)是否已有資料,如果沒有資料代表App是初次使用,接著到NASA的APOD官網下載列表清單(Retrofit2)加入資料庫。此時資料庫只會有日期與英文標題(因為列表清單只有這些資訊)。一旦資料庫有資料更動,介面就會開始更新。

另一種狀況是,如果ViewModel發現資料庫已經有資料了,也會在背景抓取APOD官網的列表清單準備更新資料。但是在抓取新列表的同時,介面已經可以跟使用者互動了。如果有發現需要更新的資料,也會把新的資料加到資料庫裡頭,同時更新介面。

除了列表清單是一律從NASA APOD英文官網抓取外,Network Repository會根據顯示的語言分別到NASA的官網或成大的中文翻譯網抓取每天的APOD詳細資料。成大的網頁其實也有英文的版本,但是網站不是很穩,所以英文還是以NASA的官網為主。

AstroPhotons除了APOD資料流外,還觀察系統的網路狀態。一旦系統察覺網路斷線了,就會發出網路已經斷線的資料流,此時App就會跳出警示,提醒使用者檢查網路。

語言的選擇以Jetpack DataStore存放。離開App時的所使用的語言就是下次開啟App時的預設語言。Jetpack DataStore存放的內容也是以data flow的方式更新介面。

keywords: Kotlin flow, state flow, coroutine, view model, MVVM, REST API, Repository pattern, separation of concern, Room, Retrofit, database, Jetpack DataStore

- 使用者介面

目前的使用者介面相當陽春,主要分成二頁: (總覽/我的收藏),(APOD詳細解說頁)

總覽/我的收藏

這個頁面以Scaffold為框架,有一個Topbar,一個Floating Action Button (FAB),以LazyVerticalGrid來呈現總覽的內容。Topbar所包含的action有"總覽/我的收藏"、"月曆"、"搜尋"、"語言"。

總覽/我的收藏: 只顯示收藏的內容或全部的列表。這是很基本的設計,根據Model裡面的isFavorite來過濾呈現的內容。

月曆: 前往選擇的日期。利用LazyGridState來達到這個效果。

搜尋: 目前主要是搜尋英文標題裡的字。使用的是Material 3的Searchbar來呈現。其實自己不是很喜歡目前Searchbar的設計。但是這個功能也確實有用,所以先將就吧。

語言: 只有英文與繁體中文之間的切換。在App裡頭直接切換有利於想學英文的使用者。一開始想設計成多語言介面,也就是介面語言與手機使用的語系同步,可是這樣想讀英文的中文使用者為了讀英文必須去切換手機語系,太麻煩了。

FAB: 考慮到使用者往下滑了一段距離後想回到列表的頂端所加的方便功能。

LazyVerticalGrid: 原本想使用LazyVerticalStaggeredGrid,但是使用起來的效能不是很好,卡卡的,而且天文圖會跳來跳去。目前還是改以固定比例(aspect ratio)的卡片來呈現畫面,雖然看起來整齊,但是有些呆板。每張圖附有二項功能: "分享"、"收藏"。目前"分享"只是很簡單的分享apod的網址,很有改善的空間。"收藏"只是把Model的isFavorite設成true而已。值得提的是如果內容是youtube,則顯示cue的畫面。這個畫面無法播放,因為上面蓋了一層Box,而且這個Box利用Modifier.clickable 吸收使用者的Tap gesture。

Pull and Refresh: 利用Modifier.pullRefresh來製作這個功能。當使用在列表的頂端持續往上捲動時會開始更新列表。背景中,App會去APOD官網下載列表,檢查有無新的項目可以更新,如果有新的項目就會即刻加入畫面。

keywords: scaffold, topbar, search bar, lazyVerticalGrid, lazyVerticalStaggeredGrid, LazyGridState, Modifier.clickable, Modifier.pullRefresh


APOD詳細解說頁









Comments