Skip to content

Commit 2b4d188

Browse files
author
alllexey
committed
Use SwipeRefreshLayout
1 parent f6e63fe commit 2b4d188

File tree

5 files changed

+47
-33
lines changed

5 files changed

+47
-33
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ dependencies {
4949
implementation(libs.androidx.preference.ktx)
5050
implementation(libs.androidx.activity)
5151
implementation(libs.androidx.constraintlayout)
52+
implementation(libs.androidx.swiperefreshlayout)
5253
testImplementation(libs.junit)
5354
androidTestImplementation(libs.androidx.junit)
5455
androidTestImplementation(libs.androidx.espresso.core)

app/src/main/java/me/alllexey123/itmowidgets/ui/schedule/ScheduleActivity.kt

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import android.content.Context
55
import android.content.Intent
66
import android.os.Bundle
77
import android.view.View
8-
import android.widget.ProgressBar
98
import android.widget.Toast
109
import androidx.activity.viewModels
1110
import androidx.appcompat.app.AppCompatActivity
1211
import androidx.recyclerview.widget.LinearLayoutManager
1312
import androidx.recyclerview.widget.PagerSnapHelper
1413
import androidx.recyclerview.widget.RecyclerView
14+
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
1515
import com.google.android.material.floatingactionbutton.FloatingActionButton
1616
import me.alllexey123.itmowidgets.ItmoWidgetsApp
1717
import me.alllexey123.itmowidgets.R
@@ -20,9 +20,10 @@ import me.alllexey123.itmowidgets.ui.settings.SettingsActivity
2020
import java.time.LocalDate
2121

2222
class ScheduleActivity : AppCompatActivity() {
23+
24+
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
2325
private lateinit var outerRecyclerView: RecyclerView
2426
private lateinit var dayScheduleAdapter: DayScheduleAdapter
25-
private lateinit var progressBar: ProgressBar
2627

2728
private lateinit var fabSettings: FloatingActionButton
2829

@@ -41,10 +42,15 @@ class ScheduleActivity : AppCompatActivity() {
4142

4243
setupRecyclerView()
4344
setupButtons()
44-
progressBar = findViewById(R.id.loadingProgressBar)
45+
swipeRefreshLayout = findViewById(R.id.swipe_refresh_layout)
46+
4547
observeUiState()
4648

47-
scheduleViewModel.fetchScheduleData()
49+
scheduleViewModel.fetchScheduleData(forceRefresh = false)
50+
51+
swipeRefreshLayout.setOnRefreshListener {
52+
scheduleViewModel.fetchScheduleData(forceRefresh = true)
53+
}
4854
}
4955

5056
private fun setupButtons() {
@@ -77,8 +83,8 @@ class ScheduleActivity : AppCompatActivity() {
7783
scheduleViewModel.uiState.observe(this) { state ->
7884
when (state) {
7985
is ScheduleUiState.Loading -> {
80-
progressBar.visibility = View.VISIBLE
81-
outerRecyclerView.visibility = View.GONE
86+
swipeRefreshLayout.isRefreshing = true
87+
outerRecyclerView.visibility = View.VISIBLE
8288
}
8389

8490
is ScheduleUiState.Success -> {
@@ -118,12 +124,12 @@ class ScheduleActivity : AppCompatActivity() {
118124
isInitialLoad = false
119125
}
120126

121-
progressBar.visibility = if (state.isCached) View.VISIBLE else View.GONE
127+
swipeRefreshLayout.isRefreshing = state.isStillUpdating
122128
outerRecyclerView.visibility = View.VISIBLE
123129
}
124130

125131
is ScheduleUiState.Error -> {
126-
progressBar.visibility = View.GONE
132+
swipeRefreshLayout.isRefreshing = false
127133
Toast.makeText(this, state.message, Toast.LENGTH_LONG).show()
128134
}
129135
}

app/src/main/java/me/alllexey123/itmowidgets/ui/schedule/ScheduleViewModel.kt

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import androidx.lifecycle.viewModelScope
77
import api.myitmo.model.Schedule
88
import kotlinx.coroutines.launch
99
import me.alllexey123.itmowidgets.data.repository.ScheduleRepository
10+
import java.time.Duration
1011
import java.time.LocalDate
1112

1213
sealed class ScheduleUiState {
1314
object Loading : ScheduleUiState()
14-
data class Success(val schedule: List<Schedule>, val isCached: Boolean) : ScheduleUiState()
15+
data class Success(val schedule: List<Schedule>, val isStillUpdating: Boolean) : ScheduleUiState()
1516
data class Error(val message: String) : ScheduleUiState()
1617
}
1718

@@ -22,24 +23,31 @@ class ScheduleViewModel(
2223
private val _uiState = MutableLiveData<ScheduleUiState>()
2324
val uiState: LiveData<ScheduleUiState> = _uiState
2425

25-
fun fetchScheduleData() {
26-
_uiState.value = ScheduleUiState.Loading
27-
26+
fun fetchScheduleData(forceRefresh: Boolean) {
2827
viewModelScope.launch {
2928
try {
3029
val startDate = LocalDate.now().minusDays(7)
3130
val endDate = LocalDate.now().plusDays(7)
3231

3332
val cachedSchedule =
3433
scheduleRepository.getCachedScheduleForRange(startDate, endDate)
35-
if (cachedSchedule.isNotEmpty()) {
36-
_uiState.postValue(ScheduleUiState.Success(cachedSchedule, true))
34+
35+
if (cachedSchedule.isNotEmpty() && !forceRefresh) {
36+
37+
val totalDays = Duration.between(startDate.atStartOfDay(), endDate.atStartOfDay()).toDays() + 1
38+
39+
if (cachedSchedule.size < totalDays) {
40+
_uiState.postValue(ScheduleUiState.Success(cachedSchedule, true))
41+
val remoteSchedule = scheduleRepository.getScheduleForRange(startDate, endDate)
42+
_uiState.postValue(ScheduleUiState.Success(remoteSchedule, false))
43+
} else {
44+
_uiState.postValue(ScheduleUiState.Success(cachedSchedule, false))
45+
}
3746
} else {
3847
_uiState.value = ScheduleUiState.Loading
48+
val remoteSchedule = scheduleRepository.getScheduleForRange(startDate, endDate)
49+
_uiState.postValue(ScheduleUiState.Success(remoteSchedule, false))
3950
}
40-
41-
val remoteSchedule = scheduleRepository.getScheduleForRange(startDate, endDate)
42-
_uiState.postValue(ScheduleUiState.Success(remoteSchedule, false))
4351
} catch (e: Exception) {
4452
val errorMessage = "Failed to update schedule: ${e.message}"
4553
_uiState.postValue(ScheduleUiState.Error(errorMessage))

app/src/main/res/layout/activity_schedule.xml

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,23 @@
77
android:orientation="vertical"
88
tools:context=".ui.schedule.ScheduleActivity">
99

10-
<androidx.recyclerview.widget.RecyclerView
11-
android:id="@+id/outerRecyclerView"
10+
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
11+
android:id="@+id/swipe_refresh_layout"
1212
android:layout_width="match_parent"
1313
android:layout_height="match_parent"
14-
android:orientation="horizontal"
15-
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
16-
android:clipToPadding="false"
17-
android:paddingEnd="8dp"
18-
android:paddingStart="8dp"/>
14+
>
1915

16+
<androidx.recyclerview.widget.RecyclerView
17+
android:id="@+id/outerRecyclerView"
18+
android:layout_width="match_parent"
19+
android:layout_height="match_parent"
20+
android:orientation="horizontal"
21+
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
22+
android:clipToPadding="false"
23+
android:paddingEnd="8dp"
24+
android:paddingStart="8dp"/>
2025

21-
<ProgressBar
22-
android:id="@+id/loadingProgressBar"
23-
android:layout_width="wrap_content"
24-
android:layout_height="wrap_content"
25-
app:layout_constraintTop_toTopOf="parent"
26-
app:layout_constraintBottom_toBottomOf="parent"
27-
app:layout_constraintStart_toStartOf="parent"
28-
app:layout_constraintEnd_toEndOf="parent"
29-
android:visibility="visible" />
26+
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
3027

3128
<com.google.android.material.floatingactionbutton.FloatingActionButton
3229
android:id="@+id/fab_qr"

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ workRuntimeKtx = "2.10.3"
1111
preferenceKtx = "1.2.1"
1212
activity = "1.8.0"
1313
constraintlayout = "2.1.4"
14+
swiperefreshlayout = "1.1.0"
1415

1516
[libraries]
1617
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -23,6 +24,7 @@ androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx"
2324
androidx-preference-ktx = { group = "androidx.preference", name = "preference-ktx", version.ref = "preferenceKtx" }
2425
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
2526
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
27+
androidx-swiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "swiperefreshlayout" }
2628

2729
[plugins]
2830
android-application = { id = "com.android.application", version.ref = "agp" }

0 commit comments

Comments
 (0)