iT邦幫忙

2024 iThome 鐵人賽

DAY 19
0

前言

昨天我們弄完了下拉刷新了功能後,要來處理另一個事情也就APP自動刷新,我們目前的APP的有個問題,如果你的APP放著過夜(過0:00),他並不會自動刷新行事曆。今天我們要來想辦法解決這個事件

自動刷新功能

1.CalendarViewModel.kt

程式碼如下

  • kotlin
package com.example.a2024ironman

import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class CalendarViewModel : ViewModel() {
    // 用來觸發刷新事件的 StateFlow
    private val _refreshEvent = MutableStateFlow(false)
    val refreshEvent: StateFlow<Boolean> = _refreshEvent

    // 當日期變更時,調用這個方法來觸發刷新
    fun triggerRefresh() {
        _refreshEvent.value = true
    }

    // 當刷新完成後,重置狀態
    fun resetRefreshState() {
        _refreshEvent.value = false
    }
}

上面這個程式碼是用來管理日曆刷新邏輯的ViewModel,它使用了StateFlow來觸發和追蹤刷新狀態,讓UI能自動更新。透過上面這個程式 UI 組件可以觀察StateFlow的狀態變化並自動更新畫面。

2.新增自動刷新邏輯

MainActivityonCreate方法中加入了一個自動刷新的邏輯。
程式碼如下

  • kotlin
import androidx.activity.viewModels // 用於在 MainActivity 中使用 ViewModel
import androidx.lifecycle.lifecycleScope // 用於在 MainActivity 中啟動協程以進行定時刷新
import kotlinx.coroutines.delay // 用於設定刷新間隔時間
import kotlinx.coroutines.launch // 用於啟動協程以定期檢查
import androidx.compose.runtime.saveable.rememberSaveable // 用於保存 `selectedDate` 和 `showDayView` 狀態
import androidx.lifecycle.viewmodel.compose.viewModel // 如果你在組合函數中使用 ViewModel 的話

lifecycleScope.launch {
    while (true) {
        delay(60000) // 每分鐘檢查一次
        calendarViewModel.triggerRefresh()  // 觸發刷新
    }
}

上面的程式碼每60秒會自動呼叫 calendarViewModel.triggerRefresh(),來觸發日曆的刷新行為。

3.新增ViewModel的refresh邏輯

CalendarLayout函式中加入了基於refreshState的刷新邏輯

  • kotlin
import androidx.activity.viewModels // 用於在 MainActivity 中使用 ViewModel
import androidx.lifecycle.lifecycleScope // 用於在 MainActivity 中啟動協程以進行定時刷新
import kotlinx.coroutines.delay // 用於設定刷新間隔時間
import kotlinx.coroutines.launch // 用於啟動協程以定期檢查
import androidx.compose.runtime.saveable.rememberSaveable // 用於保存 `selectedDate` 和 `showDayView` 狀態
import androidx.lifecycle.viewmodel.compose.viewModel // 如果你在組合函數中使用 ViewModel 的話

lifecycleScope.launch {
    while (true) {
        delay(60000) // 每分鐘檢查一次
        calendarViewModel.triggerRefresh()  // 觸發刷新
    }
}

refreshState變為true時,自動刷新事件會被觸發,並且執行 googleCalendarAuth?.fetchEvents()來取得新的事件資料。刷新結束後,會將 isRefreshing設為false並重置viewModelrefreshState狀態。

完成了上面的功能之後,現在你的app應該可以每60秒自動刷新一次,以確保你的資料是最新的,下面我們來測試一下。
我們在lifecycleScope.launch裡加入一個log來確認的他觸發狀況

  • kotlin
lifecycleScope.launch {
            while (true) {
                delay(60000)
                Log.e("lifecycleScope", "lifecycleScope ok")// 每分鐘檢查一次
                calendarViewModel.triggerRefresh()  // 觸發刷新

            }
        }

首先我先建立一個鐵人賽的事件如下圖所示
https://ithelp.ithome.com.tw/upload/images/20241003/20162649HVV3dI3rir.png
這時候APP的畫面應該會項這樣呈現,上面有今天的鐵人賽行程
https://ithelp.ithome.com.tw/upload/images/20241003/20162649oxKS7uEP1l.png
https://ithelp.ithome.com.tw/upload/images/20241003/20162649S2fZ3s8rJn.png
然後我們刪除該行程
https://ithelp.ithome.com.tw/upload/images/20241003/20162649DVYsOOSJRB.png
這時候我們等LOG訊息觸發lifecycleScope
https://ithelp.ithome.com.tw/upload/images/20241003/201626490P097SxBm2.png
這時你的APP就會自動刷新成新的內容了,如下圖所示
https://ithelp.ithome.com.tw/upload/images/20241003/20162649EbP253q8gm.png
https://ithelp.ithome.com.tw/upload/images/20241003/20162649tUnaiEC83E.png

後話

今天實作了APP刷新的功能,本來是想直接將整個APP的重新刷新,但中間出了點問題,這邊先取巧一下,透過StateFlow來觸發我們昨天的下拉刷新功能,藉此實現我們的目的,那麼今天的內容就到這邊了,讓我們明天再見。


上一篇
Day18:使用SwipeRefresh實作下拉刷新功能
下一篇
Day20:使用核取方塊元件來完成代辦事項,並將其同步到GOOGLE Task
系列文
github裡永遠有一個還沒做的SideProject :用Kotlin來開發點沒用的酷東西30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言