ReaderProgressIndicator: Convert to Compose (#9574)

This commit is contained in:
Ivan Iskandar
2023-06-04 00:11:41 +07:00
committed by GitHub
parent 0d96791a84
commit 39e4568460
5 changed files with 137 additions and 81 deletions

View File

@ -0,0 +1,110 @@
package tachiyomi.presentation.core.components
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProgressIndicatorDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.tooling.preview.Preview
/**
* A combined [CircularProgressIndicator] that always rotates.
*
* By always rotating we give the feedback to the user that the application isn't 'stuck'.
*/
@Composable
fun CombinedCircularProgressIndicator(
progress: Float,
) {
val animatedProgress by animateFloatAsState(
targetValue = progress,
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
label = "progress",
)
AnimatedContent(
targetState = progress == 0f,
transitionSpec = { fadeIn() togetherWith fadeOut() },
label = "progressState",
) { indeterminate ->
if (indeterminate) {
// Indeterminate
CircularProgressIndicator()
} else {
// Determinate
val infiniteTransition = rememberInfiniteTransition(label = "infiniteRotation")
val rotation by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = 360f,
animationSpec = infiniteRepeatable(
animation = tween(2000, easing = LinearEasing),
repeatMode = RepeatMode.Restart,
),
label = "rotation",
)
CircularProgressIndicator(
progress = animatedProgress,
modifier = Modifier.rotate(rotation),
)
}
}
}
@Preview
@Composable
private fun CombinedCircularProgressIndicatorPreview() {
var progress by remember { mutableFloatStateOf(0f) }
MaterialTheme {
Scaffold(
bottomBar = {
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
progress = when (progress) {
0f -> 0.15f
0.15f -> 0.25f
0.25f -> 0.5f
0.5f -> 0.75f
0.75f -> 0.95f
else -> 0f
}
},
) {
Text("change")
}
},
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxSize()
.padding(it),
) {
CombinedCircularProgressIndicator(progress = progress)
}
}
}
}