實作影片 Jetpack Compose Clean Architecture News App
Github mohammednawas8-NewsApp
OnBoardingScreen
HomeScreen
SearchScreen
ArticleDetail
ShareArticle
BookmarkScreen
使用 Jetpack Compose 框架建立新聞應用程式。
- 實作引導畫面,支援深/淺色模式。
- 瀏覽新聞文章,顯示頂部標題新聞。
- 進入文章詳細頁面,可點擊瀏覽器圖標閱讀完整文章,支援分享和收藏功能。
- 搜尋功能,支援類別搜尋,顯示 shimmer 效果。
- 保存文章功能,可在書籤頁面查看已保存文章。
- 使用 Jetpack Compose 開發。
- 採用清晰架構 (Clean Architecture)、MVVM 和 MVI。
- 使用 Jetpack Paging3 處理新聞分頁載入。
- 使用 Retrofit 進行網路請求。
- 整合 Room Database 本地儲存文章。
- 使用 DataStore Preferences 管理引導畫面的點擊事件。
- 使用 Dagger Hilt 進行依賴注入。
- 具備 Jetpack Compose 基礎。
- 如果尚未學習 Jetpack Compose,建議先觀看作者的 Jetpack Compose 教學系列。
- 由於專案分為 12 部分,作者在 GitHub 上設置了 12 個不同的分支,方便觀眾查看特定部分的代碼。
- 初始專案在 master 分支。
- 從 GitHub 複製遠端專案連結。
- 在 Android Studio 中選擇「File」->「New」->「Project from Version Control」。
- 貼上遠端專案連結,點擊 Clone。
- 設置 JDK 版本為 17。
- 執行專案,確保下載成功。
- 創建新的主題以實現 Splash Screen,透過進入 res/values,並創建一個名為 "Splash" 的主題。
- 新建一個名為 "AppStartingTheme" 的樣式,並設置其父主題為來自 Splash API library 的 "theme_splash_screen"。
- 在 Splash 主題中配置 Splash API,包括設置背景顏色和動畫圖標。
- 添加 "postSplashScreenTheme" 配置,以在顯示 Splash Screen 後應用主題。
- 為了實現夜間模式的 Splash Screen,創建了具有 "night" 修飾符的相應主題。
- 在夜間模式版本中,複製了日間模式版本的主題設置,並修改了相應的顏色。
- 在 Manifest 文件中更新主題配置,將應用程序主題和活動主題更改為新創建的 "AppStartingTheme"。
- 在 MainActivity 的
onCreate
函數中呼叫installSplashScreen
以啟用 Splash Screen。
- 創建
presentation
package 作為 Clean Architecture 中的一部分,用於保存 UI 相關的代碼,包括屏幕、視圖模型等。
- 在
presentation
package 中創建onboarding
package,用於保存與 Onboarding Screens 相關的代碼。 - 創建
Page
數據類,包含每個 Onboarding Screen 的標題、描述和圖片。
- 創建
onBoardingPage
的 Composable 函數,用於設計每個 Onboarding Screen 的 UI。 - 通過
Pager
和RememberPagerState
實現横向滑動的 Onboarding Screens。 - 設計 Onboarding Screen 的標題、描述和圖片。
- 在
presentation.common
package 中創建ReusableButton
的 Composable 函數,實現可重用的按鈕 UI,接受文本和回調函數。
- 在
presentation.common
package 中創建PageIndicator
的 Composable 函數,實現 Onboarding Screens 下方的頁面指示器。
- 創建
onBoardingScreen
的 Composable 函數,設計包含 Onboarding Screens、Button 和 Page Indicator 的整體 UI。
- 在這個影片中,將完成 Onboarding Screen 的設計,並且確保在每個 Onboarding Screen 中添加了底部的指示器和按鈕區域。
- 使用
Spacer
將底部的指示器和按鈕區域推到螢幕底部,使用weight
屬性確保佔據適當的空間。 - 添加
Spacer
的主要目的是在 Onboarding Screen 與系統狀態欄(status bar)和導航欄(navigation bar)之間創建空間。
- 使用
navigationBarsPadding
來計算導航欄的高度,並將其作為 padding 添加到底部的 Row 中。 - 目的是確保整個 Onboarding Screen 的設計能夠適應系統狀態欄和導航欄,實現視覺上的一致性。
- 在設計中加入之前創建的 Page Indicator,以顯示用戶當前處於的 Onboarding Screen。
- 通過
PagerState
等參數配置 Page Indicator 的顯示。
- 使用 Row 創建一個水平佈局,包含用於返回(back)的按鈕和用於進行下一步(next)的按鈕。
- 隱藏返回按鈕當用戶位於第一個 Onboarding Screen 時,以符合設計需求。
- 通過按鈕的點擊來執行相應的動作,使用
PagerState
來實現 Onboarding Screen 的滑動。 - 處理最後一個 Onboarding Screen 的情況,可以進行應用程序的啟動或導向主屏幕。
- 通過在 MainActivity 中使用
WindowCompat
並設置decorView.systemUiVisibility
來確保 Onboarding Screen 在系統狀態欄和導航欄後方繪製。
- 考慮不同主題和模式下的外觀,確保 UI 在光亮模式和夜間模式下均呈現正確。
- 未來將介紹一個更好的方法來改變狀態欄顏色,以提高代碼的可讀性和可維護性。
- Clean Architecture 是一種結構專案的方式,旨在提高專案的可維護性和可擴展性。
- 可維護性表示當專案龐大時,修復錯誤或問題不至於讓開發者難以找到相應的代碼。
- 可擴展性表示能夠方便地新增功能,而不需修改現有的代碼。
-
Data Layer
- 存放與數據相關的所有內容,包括實現存儲偏好、數據庫、網絡等的代碼。
- 提高測試性,可通過創建假存儲庫來測試數據層。
-
Domain Layer
- 包含用例、數據模型和存儲庫接口。
- 用例定義了應用程序的核心業務邏輯,數據模型表示數據結構,存儲庫接口用於定義與數據層的交互。
-
Presentation Layer
- 包含與 UI 相關的所有內容,例如視圖、可組合的 UI、視圖模型和 UI 事件。
- 大型圓圈能夠訪問小型圓圈,但反之則不行。
- 使用 Jetpack Compose 中的 Preferences Datastore 實現本地存儲。
- 創建了 Data Layer 中的
local user manager
介面,定義了保存和讀取應用程序入口的功能。 - 在 Data Layer 中實現了這個介面的具體類,使用 Preferences Datastore 保存鍵值對,以及提供了對應的操作函數。
- 在 Domain Layer 中建立了
use cases
的包,用於保存和讀取應用程序入口。 - 這些 use cases 依賴於
local user manager
介面,這使得它們更易於測試,因為可以提供不同的介面實現。
- 在下一個視頻中,將實現 Dagger Hilt,這是一個用於 Android 應用程序的依賴注入框架,用於簡化代碼和提高可測試性。
- Dagger Hilt 是一種用於 Android 應用程序的依賴注入框架,它可以方便地將依賴或對象注入到類中。
- 依賴注入的目的是將所需的依賴傳遞給類,例如在 Data Layer 中傳遞上下文(context)。
-
Application Class 的創建
- 創建了一個名為
NewsApplication
的應用程序類,繼承自Application
,並使用@HiltAndroidApp
注解。
- 創建了一個名為
-
Module 的創建
- 在
di
(dependency injection)包下創建了一個名為AppModule
的模塊。 - 透過
@Module
和@Singleton
注解,定義了模塊的生命週期為 Singleton。 - 提供了
LocalUserManager
實現的依賴注入,以及ReadAppEntry
和SaveAppEntry
用例的依賴注入。
- 在
-
依賴注入到 MainActivity
- 在
MainActivity
中使用@Inject
進行依賴注入,注入了AppEntryUseCases
。 - 在
launch
區塊中使用了ReadAppEntry
用例,並記錄了其值。
- 在
- 在 MainActivity 中發現了一個問題,需要添加
@AndroidEntryPoint
注解以確保 Dagger Hilt 的正確運作。
- 影片開始處提到要實作 Onboarding ViewModel,這是為了處理 Onboarding Screen 中的邏輯,包括保存進入應用的事件。
- 在 presentation 包下創建了 OnboardingViewModel 類別,這個類別是用來處理 Onboarding Screen 的邏輯,繼承自 ViewModel。
- 同時創建了一個 OnboardingEvent 類別,這是一個密封類別,表示可以從 UI 傳送到 ViewModel 的事件。目前只有一個事件,即保存應用進入事件。
- 在 OnboardingViewModel 中使用 Dagger Hilt 的
@HiltViewModel
進行依賴注入,注入了名為addIntroUseCase
的 Use Case。
- 在 OnboardingViewModel 中,僅暴露了一個公開函數
onEvent
用於處理從 UI 送來的事件,根據事件的不同進行相應的處理。 - 目前只處理了一種事件,即保存應用進入的事件。
- 實作了
saveAppEntry
函數,使用了注入的addIntroUseCase
進行應用進入事件的保存。 - 這個函數使用了 ViewModelScope,確保在 ViewModel 的生命週期中執行。
- 在 Onboarding Screen 中,不再直接創建 ViewModel,而是透過接口回調的方式,將按鈕點擊事件傳遞至外部,這樣的設計是為了讓 Screen 更容易進行測試和預覽。
- 在 MainActivity 中使用 Hilt 的
viewModel
函數來獲取 OnboardingViewModel 實例,然後呼叫onEvent
函數來傳遞按鈕點擊事件。
- 在 MainActivity 中,使用協程觀察
addIntroUseCase
的執行結果,並將結果輸出至 Log 中,以驗證是否成功保存了應用進入事件。
- 測試結果顯示一開始為 false,表示應用進入事件尚未保存。在點擊 "Get Started" 後,成功保存了應用進入事件,Log 中輸出了 true。
- 在 Presentation Layer 中建立
net.grab
包,並創建一個Route
類來定義不同屏幕的路徑。 - 使用密封類
Route
,其中包含不同屏幕的對象。 - 創建導航圖
NavGraph
,設置導航控制器和起始目的地。
- 使用封裝類
Route
,定義了不同屏幕的路徑和子導航圖。 - 創建了導航系統的各種屏幕,如
OnBoardingScreen
、HomeScreen
、SearchScreen
等。 - 為每個屏幕創建對應的路徑對象,並將其分類為主導航或子導航。
- 在
NavGraph
中創建導航宿主,並添加子導航圖以實現不同屏幕的導航。 - 使用
NavHost
和導航控制器來設置起始目的地和導航行為。 - 使用
navigation
函數來設置主導航和子導航的起始目的地。
- 使用 View Model 中的數據來動態決定起始目的地。
- 使用
readAppEntry
Use Case 來讀取應用程序的進入點設置。 - 根據應用程序的狀態,將起始目的地設置為主導航或子導航中的一個。
- 使用 Splash 條件來控制啟動畫面的顯示時間。
- 通過持續收集應用程序的進入點來確保啟動畫面的正確顯示。
- 使用 ViewModel 和 Composable 函數來動態設置起始目的地和啟動畫面的顯示。
- 在
MainActivity
中,使用 System UI Controller 库來更改狀態欄和導航欄的顏色。 - 創建一個
isSystemInDarkMode
的 Composable 函數來檢查系統是否處於深色模式。 - 使用
rememberSystemUiController
獲取 System UI Controller 的實例。
- 在
sideEffect
區塊中,使用systemController.setSystemBarColors
來設置系統欄的顏色。 - 將狀態欄顏色設置為
color.transparent
以實現透明效果,並根據深色模式使用負的顏色值設置深色圖標。 - 去除
values
中之前添加的項目以確保透明系統欄正常顯示。
- 啟動應用程序後,應該能夠看到透明的系統欄,既不帶顏色也不帶圖標。
- 可以在
sideEffect
區塊中更改深色圖標的顏色,並演示不同的效果。
- System UI Controller 库提供了 Compose 中操作系統 UI 的功能,例如更改狀態欄和導航欄顏色。
- 透明的系統欄可實現將 UI 延伸到狀態欄和導航欄下面,提供更流暢的使用者體驗。
- 在此視頻中,作者介紹了使用 News API 來獲取新聞數據,並指導觀眾獲取 API Key 的步驟。
- 使用 News API 提供的
everything
端點,作者示範了 API 響應的例子,並在 Kotlin 中創建了對應的數據類NewsResponse
。
- 在 Android Studio 中,作者創建了一個
remote
包,並在其中創建了一個 DTO(Data Transfer Object)包,以放置 API 響應的類。 - 使用 JSON to Kotlin Class 插件,作者將 API 響應轉換為 Kotlin 類,並進行了相應的整理和移動。
- 在
remote
包中,作者創建了一個NewsAPI
介面,使用 Retrofit 來定義 API 請求。 - 定義了一個
getNews
函數,並指定了所需的參數,包括頁碼、新聞源和 API Key。
- 在
domain
包中的repository
包裡,作者創建了一個NewsRepository
介面,並定義了一個getNews
函數,返回使用 Paging 3 Library 封裝的Flow<PagingData<Article>>
。 - 在
remote
包中,創建了一個NewsPagingSource
類,實現了PagingSource
介面,並使用 News API 進行分頁請求。 - 在
data
包中,實現了NewsRepositoryImpl
類,實現了NewsRepository
介面,並使用Pager
和NewsPagingSource
進行分頁加載。
- 在
domain
包中,作者創建了一個usecase
包,並在其中創建了一個GetNewsUseCase
類,作為使用案例。 - 使用案例中實現了一個
invoke
運算符,調用NewsRepository
的getNews
函數,返回分頁數據。
- 在這段視頻中,作者建立了 Home 界面的 ViewModel,這是一個與界面相關的組件,負責處理界面的邏輯和數據。
- 在
presentation
層的home
包中,作者創建了一個名為HomeViewModel
的類,並使其擴展自ViewModel
。 - 使用了
hiltViewModel
注解,這是 Dagger Hilt 框架提供的用於構建 ViewModel 的注解,並注入了NewsUseCases
這一用例類。
- 為了提供 ViewModel 所需的
NewsUseCases
,作者創建了一個NewsUseCases
的數據類,其中包含了GetNewsUseCase
。 - 使用 Dagger Hilt 的 DI(依賴注入)功能,在 DI 模塊中提供
NewsUseCases
,NewsRepository
以及NewsAPI
。 - 通過
hiltViewModel
注解,在HomeViewModel
中注入NewsUseCases
依賴。
- 在
HomeViewModel
中,作者定義了一個news
的成員變量,用於保存從 API 獲取的新聞數據。 - 使用
cachedIn(viewModelScope)
方法來確保數據在配置更改時不會丟失,並將其緩存在 ViewModel 的作用域內。 - 調用
newsUseCases.getNews
函數,並傳遞新聞來源(source),以獲取新聞數據。
- 在
presentation.common
包中,作者創建了一個名為ArticleCard
的 composable 函數,用於顯示新聞卡片。 - 使用
AsyncImage
來加載新聞圖片,並設置樣式和排版。 - 將新聞的標題、來源、發布時間等信息嵌入到 composable 中,並使用 Material Design 的風格進行設計。
- 在
presentation.common
包中,作者創建了一個名為ShimmerEffect
的 composable 函數,用於實現 Shimmer 效果。 - 使用自定義的
modifier
和Transition
對背景顏色的 alpha 值進行動畫過渡,創建出閃爍的效果。 - 這個 Shimmer 效果可以應用在任何需要加載時顯示的地方。
- 建立
ArticlesList
Composable,用於顯示從 Pedium 3 獲取的文章列表。 - 放置於
common
封裝中,因它將在不同畫面上重複使用。 - 參數包括
modifier
、Articles
、以及onItemClick
。 - 引入
Shimmer
效果,以處理資料載入中的視覺呈現。
- 創建
handlePagingResult
函數,用於處理分頁加載的狀態。 - 返回布林值,表示是否成功獲取文章。
- 利用
loadState
來處理載入狀態及錯誤處理。 - 針對不同的錯誤,返回相應的錯誤信息。
- 建立
HomeScreen
Composable,用於顯示主畫面。 - 包含搜尋條、新聞標題、文章列表等元素。
- 使用
LazyPagingItems
來顯示文章列表,透過ViewModel
取得文章數據。 - 實現搜尋條的點擊事件,導航至搜尋畫面。
- 新聞標題部分使用
BasicMarquee
實現水平跑馬燈效果。
- 創建
SearchBar
Composable,用於顯示搜尋條。 - 利用
InteractionSource
獲取搜尋條點擊事件,進行導航。 - 以自定義的邊框樣式區分深色和淺色主題。
- 修正搜尋條的水平填充問題,增加適當的水平填充。
- 修正文章卡片中圖片的顯示問題,確保圖片充滿容器。
- 在這一部分,開發者介紹了如何在應用程式中實現搜索功能。
- 通過在數據層的 News API 中實現一個新的搜尋端點,使用
suspend
函數searchNews
,該函數接受搜索查詢(searchQuery
)作為參數,並返回newsResponse
。 - 開發者提到使用與獲取新聞的端點相同的端點,但這次用於搜索。
- 在遠程包中,建立了一個
SearchNewsPagingSource
類,類似於之前建立的NewsPagingSource
。 - 這個
SearchNewsPagingSource
需要 API、搜索查詢和源作為參數,並且擴展了PagingSource
。 - 在
SearchNewsPagingSource
中,開發者重寫了getRefreshKey
和load
函數,以實現搜索新聞的相關邏輯。
- 在領域層的 Repository 中,開發者新增了一個函數
searchNews
,該函數接受搜索查詢作為參數,調用了之前實現的SearchNewsPagingSource
。 - 當然,這個函數最終返回了獲取的新聞數據。
- 在前端 ViewModel 中,新增了一個
SearchViewModel
類,並使用 Hilt ViewModel 進行初始化。 - 引入了新的
SearchNews
use case 用於搜索新聞,同時在 Repository 中注入了這一新的 use case。
- 在演示層的搜索包(presentation layer)中,創建了一個名為
SearchScreen
的類,該類負責展示搜索相關的 UI。 - 使用
SearchState
類來管理搜索查詢和新聞列表的狀態。 - 介紹了一個名為
SearchEvent
的事件類,用於更新搜索查詢和觸發搜索新聞的動作。 - 詳細描述了 UI 中的搜索欄位、搜尋按鈕、以及顯示新聞列表的部分。
- 在這一部分,開發者創建了一個名為
DetailsTopBar
的 composable function,主要包含了導航按鈕和三個選項:書籤、分享和瀏覽。 - 使用
TopAppBar
作為基本框架,並加入了相應的按鈕和事件處理。 - 引入
Painter
、ImageVector
和colorResource
來設計圖標和顏色。
- 在
presentation
層的details
package 中,創建了一個名為DetailsScreen
的 composable function。 - 接受文章
article
和事件event
作為參數,展示了詳細內容的 UI。 - 使用
LazyColumn
使畫面可滾動,其中包含了文章的圖片、標題和內容。
- 在
DetailsScreen
中,實現了點擊瀏覽、分享和書籤的相應功能。 - 使用
Intent
來啟動瀏覽功能,透過隱式意圖指定action
為ACTION_VIEW
,並檢查是否有應用程序可以處理此操作。 - 分享功能使用
ACTION_SEND
的隱式意圖,並將文章的 URL 作為文本內容。 - 書籤功能則透過事件
DetailsEvent
傳遞至 ViewModel 進行處理,同時觸發返回上一層的操作。
- 在預覽功能中,發現了一個 UI 錯誤,已經進行了修復,確保分享按鈕正確顯示。
- 在這一部分,開發者開始實作 Room Database,目的是能夠在本地數據庫中保存新聞文章。
- 開始於
data
層創建名為local
的新 package,這是用來存放與本地數據庫相關的類別和介面。 - 首要步驟是定義數據表(table),在
domain
層的model
中的Article
類別上使用@Entity
標註,這將被轉換為 Room Database 中的數據表。
- 在
local
package 中,創建了NewsDao
接口,它是 DAO(Data Access Object)的實現,負責訪問數據庫並執行各種操作,如插入、更新、刪除等。 - 使用
@Dao
標註,這樣 Room 就能夠生成實現這個接口的實例。 - 實現了插入(
upsert
)、刪除和獲取文章的相應方法。
- 為了將
Source
這個自定義的類型存儲到數據庫中,開發者實現了一個 Type Converter,將Source
轉換為字符串以及將字符串轉換回Source
。 - 使用
@TypeConverter
標註,並實現兩個相應的轉換方法。
- 在
NewsDatabase
類別中,擴展了RoomDatabase
並使用@Database
標註,配置數據庫的相關信息,包括數據表和版本號。 - 添加了 Type Converters 的標註,以便 Room 知道如何處理自定義類型。
- 使用 Dagger Hilt 在 DI 中提供
NewsDao
的實例。
- 在這一部分,開發者開始建立書籤(Bookmark)畫面,該畫面將顯示保存的文章列表。這是系列中的最後一個畫面,並且開發者計劃在下一個視頻中完成整個播放列表的實現。
- 一開始,進入
presentation
層,創建一個新的bookmark
package。然後創建BookmarkViewModel
以及相關的用例(use cases),這些用例將與數據層進行交互。
- 在
BookmarkViewModel
中,開發者創建了三個用例:- upsertArticle: 用於插入或更新文章。
- deleteArticle: 用於刪除文章。
- selectArticles: 用於選擇或檢索文章列表。
- 這些用例與
NewsDao
進行交互,並在BookmarkViewModel
中進行調用。
- 創建
BookmarkScreen
,使用 Compose 構建 UI。在這個畫面中,首先設置了畫面的基本結構,包括標題和相關的樣式設置。 - 使用
ArticlesList
組件顯示保存的文章列表,同時實現了點擊文章後導航到詳細信息畫面的功能。 - 在
BookmarkScreen
中,還有一個私有方法getArticles
,用於從數據層獲取文章列表並更新 UI。 - 透過
BookmarkViewModel
獲取數據,並在 UI 中顯示。
- 開發者在這一部分建立了 Details Screen,同時創建了 Details ViewModel 並擴展了 FrontViewModel 和 HealthViewModel。
- 在 Details ViewModel 中,引入了一個稱為 "side effect" 的可變狀態,用於處理在 Details Screen 中的事件,並使用 Nullable String 來表示目前的 side effect。
- 創建了兩個事件:upsert/delete article 和 remove side effect。這些事件與 News Use Cases(新聞用例)進行交互,實現對文章的插入、更新、刪除以及處理 side effect。
- 創建了 News Bottom Navigation,使用 Compose 實現底部導航欄,允許切換不同的屏幕。
- 在 News Navigator Screen 中,使用 Scaffold(組成 UI 的一個材料風格組件)設置應用的基本結構,包括頂部工具欄和底部導航欄。同時創建了不同的 Composable 函數來顯示不同的屏幕。
- 引入了 Bottom Navigation 的顯示狀態,使用 remember 和 back stack state 來控制 Bottom Navigation 的顯示與隱藏。
- 當處於 Home、Search 或 Bookmark Screen 時,顯示 Bottom Navigation,否則隱藏。這是通過 back stack state 來實現的。
- 在 Details Screen 中,當觸發事件時,使用 Side Effect 通知用戶有相應的操作發生。同時,該 Side Effect 會在顯示後被移除,以確保下次操作不會重複通知。
- 在執行中發現 Bookmark 列表顯示順序需要反轉。這是通過在 Bookmark ViewModel 中對列表進行反轉來實現的。
- 使用 on each 和 reverse 方法,確保在 UI 中顯示的順序是反轉的,達到期望的效果。
- Splash Screen: 一種在應用程序啟動時顯示的短暫界面,用於提供品牌標誌或應用程序入口。在這裡,使用 Splash API library 實現了 Splash Screen。
- Theme: 定義應用程序的外觀和風格的一組風格和資源配置。在這裡,創建了日間和夜間模式下的 Splash Screen 主題。
- Night Mode: 夜間模式是應用程序的一種顯示模式,通常使用較暗的顏色和低亮度,以減少對用戶眼睛的刺激。在這裡,實現了夜間模式的 Splash Screen。
- Manifest File: Android 應用程序的清單文件,包含應用程序的配置信息,例如主題、活動和權限等。
- installSplashScreen: 一個函數,用於啟用 Splash Screen。在這裡,於 MainActivity 中的
onCreate
函數中呼叫了該函數。 - Post Splash Screen Theme: Splash Screen 顯示後應用的主題配置。在這裡,配置了在 Splash Screen 後應用的主題。
- Experimental Foundation Api
- Clean Architecture: 一種結構專案的方法,旨在提高可維護性、可擴展性,並使專案更易測試。它將專案分為三層:Data Layer、Domain Layer、Presentation Layer。
- Data Layer: 存放與數據相關的代碼,包括實現存儲偏好、數據庫、網絡等的內容。提高測試性,可通過創建假存儲庫測試數據層。
- Domain Layer: 包含用例、數據模型和存儲庫接口。用例定義了核心業務邏輯,數據模型表示數據結構,存儲庫接口定義與數據層的交互。
- Presentation Layer: 包含與 UI 相關的代碼,例如視圖、可組合的 UI、視圖模型和 UI 事件。具有對 Data Layer 和 Domain Layer 的訪問權限。
- Preferences Datastore: Jetpack Compose 中的一種工具,用於實現本地存儲。用來保存鍵值對,提供了方便的 API 來處理應用程序的配置數據。
- Use Cases: 在 Domain Layer 中的包,包含了定義應用程序功能的高級業務邏輯。這裡特指保存和讀取應用程序入口的 use cases。
- Dagger Hilt: 一個用於 Android 應用程序的依賴注入框架。用於簡化代碼、提高可測試性,並使代碼更容易理解和維護。
- Dagger Hilt: 一個用於 Android 應用程序的依賴注入框架。通過注入依賴或對象,使代碼更容易理解、測試和維護。
- Dependency Injection (DI): 一種軟體設計模式,其中一個類的依賴關係由外部注入,而不是在類內部創建。這有助於降低類之間的耦合性。
- Application Class: Android 應用程序中的一個類,用於管理應用程序的全局狀態。在這裡,創建了
NewsApplication
並用於 Dagger Hilt 的設置。 - Module: Dagger Hilt 中的概念,表示一個模組,其中定義了依賴的提供方式。在這裡,
AppModule
定義了需要提供的依賴。 - Singleton: 一種生命週期,表示只有一個實例存在。在 Dagger Hilt 中,使用
@Singleton
標記模組,使其生命週期為 Singleton。 - @Inject: Dagger Hilt 中的注解,用於標記需要進行依賴注入的構造函數或屬性。
- @HiltAndroidApp: Dagger Hilt 中的注解,用於標記應用程序的
Application
類,以進行 Dagger Hilt 的初始化。 - AndroidEntryPoint: Dagger Hilt 中的注解,用於標記 Android 組件,以通知 Dagger Hilt 將依賴注入到該組件中。在這裡,用於
MainActivity
。 - Pager: 一種用於實現橫向或縱向滑動效果的 Jetpack Compose 組件,用於顯示多個屏幕或頁面。
- RememberPagerState: 一個 Jetpack Compose 中的 State,用於保持 Pager 的狀態,例如當前頁面索引。
- Composable Function: Jetpack Compose 中的一種函數,用於定義 UI 元素的可組合組件。
- Reusable Component: 可重用的 UI 元素或組件,可以在應用程序的不同部分或不同屏幕中使用。
- Page Indicator: 用於指示當前頁面的 UI 元素,通常是一組小圓點或其他符號。
- Clean Architecture: 一種軟件架構模式,強調將應用程序代碼分為不同的層次,例如 Presentation、Domain、Data 等,以實現可維護性和可擴展性。
- Drawable Resource: 在 Android 開發中,用於存儲圖像等可繪內容的資源。
- State: 在 Jetpack Compose 中,用於表示 UI 的可變數據,當數據更改時,UI 會自動刷新。
- Modifier: 在 Jetpack Compose 中,用於修改或應用樣式的屬性,例如大小、位置、填充等。
- Spacer: 用於在 Jetpack Compose 中創建空白區域,調整元素之間的間距。
- Typography: 與文本風格和字體相關的概念,在 Jetpack Compose 中用於定義文本的外觀。
- Preview Function: 用於在開發過程中快速預覽 Compose 函數的效果,以方便調試和設計。
- Background Color: UI 元素的背景色,通常根據 Material Theme 或自定義配置。
- UI Components: 構成應用程序用戶界面的基本元素,例如按鈕、文本、圖片等。
- Content Description: 在 Android 開發中,用於描述 UI 元素的輔助功能文本,通常用於可訪問性。
- Circular Shape: 表示 UI 元素的圓形形狀。
- Jetpack Compose Theme: 用於定義應用程序外觀的配置,包括顏色、字體等。
- Light Theme / Night Mode: 應用程序的不同外觀模式,分別適應亮度和暗度環境。
- Clip: 在 Compose 中,用於將 UI 元素裁剪為指定形狀或大小的操作。
- Modifier: 在 Compose 中,用於修改或定義 UI 元素的屬性。
- Primary Color: 在 Material Theme 中,表示應用程序主要顏色,通常是突出顯示的顏色。
- Reproducible Bug: 可以在開發環境中再現的錯誤,有助於開發人員進行調試和修復。
- Jetpack Compose Split: 用於在開發中實時查看 Compose UI 效果的工具。
- Horizontal Pager: 在 Jetpack Compose 中,實現橫向滑動效果的 Pager 組件。
- 引導畫面 (Onboarding Screens): 第一次啟動應用程式時,向用戶顯示的介紹性畫面,通常包含教育性內容和功能介紹。
- Clean Architecture: 軟體設計架構的一種方法,強調將代碼分為不同的層次 (如表示層、業務邏輯層、數據層) 以實現模組化和可維護性。
- Composable: 在 Jetpack Compose 中的 UI 元素,是以函數的形式構建並支援組合式 UI 開發。
- DataStore Preferences: Android 中的數據存儲庫,用於存儲應用程式的配置和簡單的鍵值對數據。
- PagerState: 在 Jetpack Compose 中用於管理分頁的狀態的類。
- rememberPagerState: Jetpack Compose 中的鉤子,用於保留分頁狀態。
- remember: Jetpack Compose 中的鉤子,用於保存可變數據,以便在重新構建期間保留其值。
- deriveStateOf: 由
remember
提供的鉤子,用於計算狀態的衍生狀態,以實現更複雜的邏輯。 - 水平分頁 (Horizontal Pager): 在 Compose 中用於支援水平滑動並顯示多個項目的 UI 元素。
- Material Theme: Android 中的 UI 設計樣式,提供預先定義的顏色、樣式和元件。
- Spacer: 在 Compose 中用於創建空白區域的元素,通常用於調整元素之間的間距。
- Navigation Bar Padding: 用於計算導航欄高度的 Modifier,確保 UI 在導航欄的存在下有適當的空間。
- Page Indicator: 顯示當前頁面的 UI 元素,通常是一組小圓點或其他符號,用於引導用戶的位置。
- PagerState: 在 Jetpack Compose 中用於跟踪 Pager 的狀態,例如當前頁面索引。
- System Bars: 在 Android 中指系統狀態欄(status bar)和導航欄(navigation bar)的組合。
- WindowCompat: 用於支持不同 Android 版本中 Window 的兼容性工具。
- Light Mode / Night Mode: 應用程序的不同主題模式,分別適應亮度和暗度環境。
- UI Behind System Bars: 確保 UI 元素能夠在系統狀態欄和導航欄的後方正確顯示。
- Animate Scroll To Page: 使用
PagerState
中的animateScrollToPage
函數實現平滑的頁面滾動效果。 - DecorView: 在 Android 中表示 Activity 的根 View,通常用於操作整個 Activity 的 UI。
- SystemUiVisibility: 用於設置 DecorView 的系統 UI 的可見性,例如隱藏或顯示狀態欄和導航欄。
- Theme and Mode Handling: 確保應用程序能夠在不同的主題和模式下呈現一致的外觀。
- CoroutineScope.launch: 使用 Kotlin 協程啟動一個新的協程,處理非同步任務。
- DataStore Preferences: 將用戶的操作(例如點擊 "Get Started")保存在本地,通常使用 DataStore 實現。
- Jetpack Compose Split: 用於實時查看 Compose UI 效果的工具,通常在開發過程中使用。
- Named Attribute: 在 Compose 中,指定屬性的方式,通常用於提高可讀性和代碼的清晰性。
- Spacer: 在 Compose 中用於添加間距和區隔 UI 元素的組合元素。
- Row: Compose 中的元素,用於水平排列子元素。
- Column: Compose 中的元素,用於垂直排列子元素。
- PagerState: 在 Jetpack Compose 中用於處理分頁和滑動的狀態的類。
- animateScrollToPage: PagerState 中的函數,用於平滑滑動到指定頁面。
- rememberCoroutineScope: Compose 中的鉤子,用於獲取協程範圍,以便進行異步操作。
- launch: 協程範圍的函數,用於啟動異步任務。
- WindowCompat: Android 中的支援庫,用於處理窗口相關的設置,如系統欄的顯示。
- setDecorFitsSystemWindows: 設置是否將畫面延伸到系統欄後面。
- windowTranslucentStatus 和 windowTranslucentNavigation: 設置系統欄是否半透明的屬性。
- ViewModel: 在 Android 架構組件中,用於管理 UI 相關數據以及處理 UI 邏輯的類別。ViewModel 被設計為能夠存儲和管理 UI 相關數據,並且在配置更改(如屏幕旋轉)時保持數據的狀態。
- Dagger Hilt: 一個用於 Android 應用程式的依賴注入框架,它簡化了 Dagger 2 的使用,並提供更容易的配置和集成。
- Use Case: 在軟體開發中,一個用於執行特定任務或功能的獨立模塊。在這裡,
addIntroUseCase
可能是一個用於處理應用進入事件的 Use Case。 - CoroutineScope: 用於啟動 Kotlin 協程的界面,確保協程在特定的生命週期內運行。在這裡,使用了 ViewModelScope 來確保
saveAppEntry
函數在 ViewModel 的生命週期內執行。 - LiveData: 在 Android 中用於在數據更改時通知觀察者的一個可觀察的數據持有者。在這裡,可能使用 LiveData 來觀察 Use Case 的執行結果,並在 UI 中進行相應的更新。
- Log: 在 Android 開發中,用於輸出調試信息的一種機制,通常使用
Log.d
或其他相關方法來輸出訊息。 - Coroutine: 在 Kotlin 中提供的異步編程框架,用於處理非同步任務,避免阻塞主線程。在這裡,使用了協程來執行非同步的 Use Case。
- Hilt ViewModel: Dagger Hilt 中用於注入 ViewModel 的擴展,簡化了 ViewModel 的依賴注入。
- Sealed Class: 一個用於表示有限集合類型的 Kotlin 類別。在這裡,
OnboardingEvent
是一個密封類別,用於表示可能從 UI 傳送到 ViewModel 的事件。 - 導航圖(NavGraph):在 Jetpack Compose 中用於定義應用程序的導航結構的組件。
- 導航控制器(NavController):在 Android 中用於管理應用程序導航的組件,可用於在不同屏幕之間進行導航。
- 應用程序進入點(App Entry Point):應用程序的起始點,可以是引導屏幕、主屏幕或其他任何應用程序的入口。
- 封裝類(Sealed Class):在 Kotlin 中用於表示受限的類型層級集合,通常用於表示固定數量的可能類型。
- View Model:在 Android 中用於管理 UI 相關數據並在配置更改時保存狀態的組件。
- System UI Controller:Compose 中的庫,用於操作 Android 系統 UI,例如調整狀態欄和導航欄的外觀。
- Composable 函數:Compose 框架中的函數,用於定義 UI 的可組合元素。
rememberSystemUiController
:Compose 中的功能,用於獲取 System UI Controller 的實例,以便在 Composable 函數中使用。sideEffect
:Compose 中的區塊,用於執行在成功重新組合時觸發的副作用代碼。- 透明效果:通過將顏色設置為
color.transparent
,使系統欄變為透明,允許 UI 在其下方顯示,提供更清晰的畫面。 - API Key:用於識別和授權 API 請求的密鑰,確保僅授權的用戶能夠訪問 API。
- Endpoints:API 提供的不同端點,每個端點都代表一個特定的功能或數據集。
- Data Transfer Object (DTO):用於在不同層之間傳輸數據的對象,通常用於將 API 響應轉換為應用程序中使用的數據類。
- Retrofit:Android 上用於進行簡化的 HTTP 請求的庫,用於與 Web 服務進行通信。
- Paging 3 Library:Android Architecture Components 中的庫,用於實現列表分頁和異步數據加載,提高性能和效率。
- Paging Source:Paging 3 Library 中的一個抽象類,用於定義如何從數據源(如 API 或數據庫)中加載數據。
- Use Case:在軟體開發中,表示應用程序執行的某一功能或操作的獨立單元,有助於保持代碼的模塊化和可測試性。
- ViewModel:一種 Android Architecture Components,用於以可感知生命周期的方式管理和存儲與 UI 相關的數據。
- Dagger Hilt:一個 Android 中用於依賴注入的框架,簡化了構建應用程序的過程,並提高了代碼的可測試性。
- DI (依賴注入):一種設計模式,用於實現類與其依賴之間的解耦,通過注入依賴實現對象的創建和管理。
- hiltViewModel:Dagger Hilt 框架提供的一個注解,用於構建 ViewModel,並透過 DI 注入相應的依賴。
- Coroutine ViewModel Scope:ViewModel 的作用域,用於在 ViewModel 的生命周期中運行協程,確保當 ViewModel 存在時協程能夠運行。
- AsyncImage:Coil 库提供的一個 composable 函數,用於異步加載圖片,支持在 Compose 中使用協程。
- Shimmer Effect:一種 UI 效果,通常用於指示數據正在加載中。在這裡,通過改變背景顏色的 alpha 值實現閃爍效果。
- Jetpack Compose: 一個由 Android 提供的現代 UI 工具包,使用 Kotlin 語言構建 UI 界面。
- Composable: 在 Jetpack Compose 中,表示一個可以構建 UI 元素的函數或元件。
- Lazy Paging Items: 一種用於分頁顯示數據的組件,當需要顯示大量數據時,只載入當前可見的部分,提高性能。
- Shimmer Effect: 一種用於指示數據載入中的視覺效果,常用於顯示虛擬的光影。
- ViewModel: 用於管理並保存 UI 相關數據的 Android 架構元件。
- Basic Marquee: Jetpack Compose 中的實驗性特性,提供簡單的水平跑馬燈效果。
- Interaction Source: 提供 UI 事件的源頭,用於捕捉和處理使用者的交互動作。
- Derived State of: 用於基於其他狀態計算新的狀態,確保 UI 保持同步。
- Content Scale: 用於指定圖片在容器中的縮放方式,例如 Crop 表示裁剪填滿。
- Marquee: 一種文本或圖片在界面上水平滾動的效果。
- Manifest File: Android 應用的清單文件,包含應用的配置和權限等信息。
- Search News Paging Source: 用於實現搜索功能的分頁數據源,擴展自 Android Jetpack 中的
PagingSource
,處理新聞搜索的請求和分頁數據加載。 - Use Case: 在軟體開發中,代表一個特定的用例或功能,通常是一個業務邏輯操作的抽象層,將 UI 和數據層分開。
- Hilt ViewModel: 使用 Hilt 框架進行依賴注入的 ViewModel,使得 ViewModel 的實例可以被自動管理和注入相依的組件。
- MutableState: 一種 Kotlin 中的數據類型,代表一個可變的狀態,可以通知觀察者當數據發生變化。
- PagingSource: Android Jetpack 中用於實現分頁加載的抽象類型,管理數據的分頁載入和緩存。
- ViewModel Scope: 用於確保 ViewModel 中的操作在特定生命周期內運行的區域,避免內存泄漏和意外的生命週期問題。
- Composable Function: Jetpack Compose 中的概念,表示一個可組合的 UI 元素,用於構建應用程序的界面。
- TopAppBar: Jetpack Compose 中的一種 UI 元素,用於在頂部顯示應用程序的標題欄,通常包含導航按鈕和操作按鈕。
- LazyColumn: Jetpack Compose 中的組合元素,用於顯示可滾動的垂直列,僅在需要時才加載和顯示可見的項目,用於提高性能。
- Intent: 在 Android 中,用於在應用程序之間執行操作的對象,可以啟動活動、服務或廣播接收器。
- 隱式 Intent: 指定操作,但不指定要執行該操作的確切組件,由系統選擇最合適的組件。
- ViewModel: Android 架構組件,用於存儲和管理 UI 相關的數據,並在配置更改時保持數據的一致性。
- Painter: Compose 中用於繪製可縮放的矢量圖形的類型。
- ImageVector: 表示可縮放的矢量圖形,通常用於顯示圖標和圖片。
- MutableState: Jetpack Compose 中的數據類型,表示一個可變的狀態,當數據發生變化時會通知觀察者。
- Implicit Intent: 由系統選擇要執行的組件的 Intent,不指定確切的組件。
- URI: 統一資源標誌符,用於標識和定位網路上的資源,如網頁或文件。
- ViewModel Scope: 用於確保 ViewModel 中的操作在特定生命周期內運行的區域,防止內存泄漏和生命周期問題。
- Room Database: Android 中的一個持久性數據庫解決方案,基於 SQLite,提供了一個用於數據訪問和操作的抽象層。
- DAO (Data Access Object): 用於定義數據庫操作的介面或類別,通常包括插入、更新、刪除和查詢等方法。
- Entity: 在 Room Database 中,表示映射到數據庫表的 Java/Kotlin 對象的類別。
- Type Converter: 用於將非標準數據類型轉換為 Room Database 可以處理的基本數據類型的工具,通常用於自定義類型的處理。
- Dagger Hilt: 一個 Android 平台上的依賴注入框架,用於管理應用程序中的對象和其相依關係。
- DI (Dependency Injection): 一種軟體設計模式,通過將對象的創建和相依關係的管理交給外部系統,以實現松散耦合和更好的可測試性。
- LiveData: Android 架構組件,用於在數據發生變化時通知觀察者,特別適用於構建反應性 UI。
- Coroutines: Kotlin 語言的非同步編程框架,用於更簡潔和可讀的非阻塞程式碼撰寫。
- Bookmark Screen: 指書籤畫面,用於顯示已保存文章的列表。
- ViewModel: 在 Android 中,用於處理 UI 相關數據和業務邏輯的組件,有助於確保 UI 組件的獨立性。
- Use Cases: 代表應用程序中的一個功能,包含了相關的業務邏輯。在這裡,用於處理與數據庫的交互操作。
- Lazy Column: 在 Jetpack Compose 中的組件,用於顯示垂直滾動的數據列表。透過
Lazy Column
,開發者可以實現僅加載當前可見項目的效果,提高性能。 - Navigate: 在 Android 中的 Compose 框架中,用於實現屏幕之間的導航,使得應用程序能夠在不同畫面間切換。
- News Navigator Screen: 負責導航應用程式的主要畫面,管理不同功能和模塊的畫面切換,通常包括底部導航欄。
- Details ViewModel: 負責處理詳細畫面的業務邏輯和狀態管理的 ViewModel。
- Side Effect: 表示在執行某些操作時引起的額外效果,例如在 UI 中顯示提示消息。在這裡,使用 MutableStateFlow 來管理 Side Effect。
- Bottom Navigation: 一種 UI 元素,通常位於畫面底部,提供導航到應用程式的不同部分的快速入口。在 Compose 中,使用
BottomNavigation
來實現。 - Compose Scaffold: Compose 框架中的一個組件,用於構建具有通用外觀的應用程式畫面。它包括頂部導航欄、底部導航欄等部分,可以輕鬆配置。
- Side Effect: 在這裡指的是一種用於通知 UI 有相關操作發生的概念,例如成功保存文章或刪除文章。在 Details Screen 中,使用 MutableState<String?> 來表示 side effect。
- Scaffold: 一種在 Compose 中使用的材料風格組件,用於構建 UI 的基本結構,包括頂部工具欄、底部導航欄等。
- Bottom Navigation: 底部導航欄,用於在應用程序的不同部分之間進行快速切換。
- Back Stack State: 在 Android 中,指導航堆棧的狀態,通常用於管理應用程序中各個屏幕之間的轉換和返回操作。
- ViewModel: 在 Android 中的 MVVM 架構中,用於處理 UI 相關邏輯和數據持久性的組件,確保 UI 的獨立性。
- Compose: Jetpack Compose,一個用於構建 Android UI 的現代 UI 工具包。
- Use Cases: 在軟體開發中,指應用程序中某個功能的使用場景或用例,以確保業務邏輯的清晰分離。
- MutableState: 在 Compose 中,一種可變的狀態,用於跟踪 UI 中的數據變化並觸發 UI 更新。
- Repository: 一種模式,用於將數據庫操作和數據來源的交互隔離,提供統一的接口供應用程序使用。
- Reverse: 將順序或列表進行反轉,改變元素的排列順序,以達到反向顯示的效果。