add pull to refresh mechanism on android home screen

This commit is contained in:
Satindar Dhillon 2022-12-09 16:30:53 -08:00
parent fcb4e859f8
commit 52fc21b0ad
2 changed files with 61 additions and 22 deletions

View file

@ -7,6 +7,10 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
@ -14,6 +18,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import app.omnivore.omnivore.Routes
import app.omnivore.omnivore.models.LinkedItem
@ -50,6 +55,7 @@ fun HomeView(
}
}
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun HomeViewContent(
homeViewModel: HomeViewModel,
@ -58,35 +64,53 @@ fun HomeViewContent(
) {
val context = LocalContext.current
val listState = rememberLazyListState()
val pullRefreshState = rememberPullRefreshState(
refreshing = homeViewModel.isRefreshing,
onRefresh = { homeViewModel.refresh() }
)
val linkedItems: List<LinkedItem> by homeViewModel.itemsLiveData.observeAsState(listOf())
LazyColumn(
state = listState,
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.background(MaterialTheme.colorScheme.background)
Box(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 6.dp)
.pullRefresh(pullRefreshState)
) {
items(linkedItems) { item ->
LinkedItemCard(
item = item,
onClickHandler = {
if (item.isPDF()) {
val intent = Intent(context, PDFReaderActivity::class.java)
intent.putExtra("LINKED_ITEM_SLUG", item.slug)
context.startActivity(intent)
} else {
navController.navigate("WebReader/${item.slug}")
LazyColumn(
state = listState,
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
.padding(horizontal = 6.dp)
) {
items(linkedItems) { item ->
LinkedItemCard(
item = item,
onClickHandler = {
if (item.isPDF()) {
val intent = Intent(context, PDFReaderActivity::class.java)
intent.putExtra("LINKED_ITEM_SLUG", item.slug)
context.startActivity(intent)
} else {
navController.navigate("WebReader/${item.slug}")
}
}
}
)
)
}
}
}
InfiniteListHandler(listState = listState) {
homeViewModel.load()
InfiniteListHandler(listState = listState) {
homeViewModel.load()
}
PullRefreshIndicator(
refreshing = homeViewModel.isRefreshing,
state = pullRefreshState,
modifier = Modifier.align(Alignment.TopCenter)
)
}
}

View file

@ -1,5 +1,8 @@
package app.omnivore.omnivore.ui.home
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -7,6 +10,8 @@ import app.omnivore.omnivore.models.LinkedItem
import app.omnivore.omnivore.networking.Networker
import app.omnivore.omnivore.networking.search
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject
@ -26,6 +31,7 @@ class HomeViewModel @Inject constructor(
// Live Data
val searchTextLiveData = MutableLiveData("")
val itemsLiveData = MutableLiveData<List<LinkedItem>>(listOf())
var isRefreshing by mutableStateOf(false)
fun updateSearchText(text: String) {
searchTextLiveData.value = text
@ -37,6 +43,11 @@ class HomeViewModel @Inject constructor(
}
}
fun refresh() {
isRefreshing = true
load(true)
}
fun load(clearPreviousSearch: Boolean = false) {
if (clearPreviousSearch) {
cursor = null
@ -69,6 +80,10 @@ class HomeViewModel @Inject constructor(
items = items.plus(searchResult.items)
itemsLiveData.value = items
}
CoroutineScope(Dispatchers.Main).launch {
isRefreshing = false
}
}
}