Add custom loader on the HomeScreen
This commit is contained in:
parent
76a5e6dd84
commit
4c98949bb6
2 changed files with 108 additions and 23 deletions
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.pixelized.biblib.ui.composable
|
||||||
|
|
||||||
|
import androidx.compose.animation.Crossfade
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material.*
|
||||||
|
import androidx.compose.material.pullrefresh.PullRefreshState
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
|
@Composable
|
||||||
|
fun Loader(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
isLoading: State<Boolean>,
|
||||||
|
refreshState: PullRefreshState
|
||||||
|
) {
|
||||||
|
val state = rememberLoaderState(refreshState)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = modifier,
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
Divider()
|
||||||
|
|
||||||
|
Crossfade(targetState = isLoading.value) { loading ->
|
||||||
|
if (loading) {
|
||||||
|
LinearProgressIndicator(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(shape = CircleShape)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(height = state.height)
|
||||||
|
.fillMaxWidth(fraction = state.faction)
|
||||||
|
.background(
|
||||||
|
shape = CircleShape,
|
||||||
|
color = state.color,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun rememberLoaderState(
|
||||||
|
refreshState: PullRefreshState,
|
||||||
|
): LoaderState {
|
||||||
|
val color = MaterialTheme.colors.primary
|
||||||
|
|
||||||
|
val state by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
LoaderState(
|
||||||
|
color = color.copy(
|
||||||
|
alpha = (3f * refreshState.progress / 4f + 0.25f).coerceIn(0f, 1f))
|
||||||
|
,
|
||||||
|
height = 1.dp + 2.dp * refreshState.progress,
|
||||||
|
faction = refreshState.progress * 0.75f,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
data class LoaderState(
|
||||||
|
val color: Color,
|
||||||
|
val height: Dp,
|
||||||
|
val faction: Float,
|
||||||
|
)
|
||||||
|
|
@ -25,10 +25,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.*
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
|
||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
@ -42,6 +39,7 @@ import com.pixelized.biblib.model.search.FilterType
|
||||||
import com.pixelized.biblib.model.search.SortType
|
import com.pixelized.biblib.model.search.SortType
|
||||||
import com.pixelized.biblib.model.search.SortValue
|
import com.pixelized.biblib.model.search.SortValue
|
||||||
import com.pixelized.biblib.ui.LocalSnackHostState
|
import com.pixelized.biblib.ui.LocalSnackHostState
|
||||||
|
import com.pixelized.biblib.ui.composable.Loader
|
||||||
import com.pixelized.biblib.ui.composable.colorElevation
|
import com.pixelized.biblib.ui.composable.colorElevation
|
||||||
import com.pixelized.biblib.ui.composable.scaffold.*
|
import com.pixelized.biblib.ui.composable.scaffold.*
|
||||||
import com.pixelized.biblib.ui.navigation.LocalScreenNavHostController
|
import com.pixelized.biblib.ui.navigation.LocalScreenNavHostController
|
||||||
|
|
@ -59,6 +57,7 @@ import com.pixelized.biblib.utils.extention.bibLib
|
||||||
import com.pixelized.biblib.utils.extention.imeHeight
|
import com.pixelized.biblib.utils.extention.imeHeight
|
||||||
import com.pixelized.biblib.utils.extention.navigationBarsHeight
|
import com.pixelized.biblib.utils.extention.navigationBarsHeight
|
||||||
import com.skydoves.landscapist.glide.GlideImage
|
import com.skydoves.landscapist.glide.GlideImage
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
@ -105,14 +104,7 @@ fun HomeScreen(
|
||||||
val largeGridState = rememberLazyGridState()
|
val largeGridState = rememberLazyGridState()
|
||||||
val smallListState = rememberLazyListState()
|
val smallListState = rememberLazyListState()
|
||||||
val microListState = rememberLazyListState()
|
val microListState = rememberLazyListState()
|
||||||
val refreshState = rememberPullRefreshState(
|
val refreshState = rememberPullRefreshState(viewModel = bookViewModel)
|
||||||
refreshing = false,
|
|
||||||
onRefresh = {
|
|
||||||
scope.launch {
|
|
||||||
bookViewModel.updateLibrary()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
FilterBottomSheet(
|
FilterBottomSheet(
|
||||||
sheetState = filterState,
|
sheetState = filterState,
|
||||||
|
|
@ -358,18 +350,13 @@ private fun HomeScreenContent(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
loader = {
|
loader = {
|
||||||
Box(
|
Loader(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
.height(1.dp)
|
.height(3.dp),
|
||||||
) {
|
refreshState = refreshState,
|
||||||
Divider()
|
isLoading = isLoading,
|
||||||
if (isLoading.value) {
|
)
|
||||||
LinearProgressIndicator(
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
content = {
|
content = {
|
||||||
val navigationBarsHeight = navigationBarsHeight()
|
val navigationBarsHeight = navigationBarsHeight()
|
||||||
|
|
@ -607,6 +594,22 @@ private fun BookList(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
|
private fun rememberPullRefreshState(
|
||||||
|
viewModel: BookSearchViewModel,
|
||||||
|
scope : CoroutineScope = rememberCoroutineScope()
|
||||||
|
): PullRefreshState {
|
||||||
|
return rememberPullRefreshState(
|
||||||
|
refreshing = viewModel.updating.value,
|
||||||
|
onRefresh = {
|
||||||
|
scope.launch {
|
||||||
|
viewModel.updateLibrary()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun CollapseKeyboardOnScrollHandler(
|
private fun CollapseKeyboardOnScrollHandler(
|
||||||
|
|
@ -651,7 +654,7 @@ private fun HomeScreenPreview() {
|
||||||
onSort = { },
|
onSort = { },
|
||||||
onDisplay = { },
|
onDisplay = { },
|
||||||
isLoading = remember { mutableStateOf(false) },
|
isLoading = remember { mutableStateOf(false) },
|
||||||
refreshState = rememberPullRefreshState(refreshing = false, onRefresh = { }),
|
refreshState = rememberPullRefreshState(refreshing = false, onRefresh = { }),
|
||||||
display = remember { mutableStateOf(HomeDisplay.MICRO) },
|
display = remember { mutableStateOf(HomeDisplay.MICRO) },
|
||||||
gridState = rememberLazyGridState(),
|
gridState = rememberLazyGridState(),
|
||||||
items = thumbnailPreviewResources(),
|
items = thumbnailPreviewResources(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue