mirror of
https://github.com/androidx/media.git
synced 2025-04-29 22:36:54 +08:00
Demo animated content scale
This commit is contained in:
parent
4c31f4a84b
commit
1beaa553ea
@ -21,6 +21,9 @@ import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.animate
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@ -30,15 +33,20 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.ScaleFactor
|
||||
import androidx.compose.ui.layout.lerp
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.LifecycleResumeEffect
|
||||
@ -124,7 +132,7 @@ private fun MediaPlayerScreen(player: Player, modifier: Modifier = Modifier) {
|
||||
player = player,
|
||||
surfaceType = SURFACE_TYPE_SURFACE_VIEW,
|
||||
modifier = Modifier.noRippleClickable { showControls = !showControls },
|
||||
contentScale = contentScales[currentContentScaleIndex].second
|
||||
contentScale = contentScales[currentContentScaleIndex].second.interpolate()
|
||||
)
|
||||
if (!renderingState.renderedFirstFrame) {
|
||||
// hide the surface that is being prepared behind a scrim
|
||||
@ -147,3 +155,87 @@ private fun MediaPlayerScreen(player: Player, modifier: Modifier = Modifier) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
private fun ContentScale.interpolate(): ContentScale {
|
||||
var interpolation by remember {
|
||||
mutableFloatStateOf(1f)
|
||||
}
|
||||
var previousScale by remember {
|
||||
mutableStateOf(this)
|
||||
}
|
||||
val currentScale by remember {
|
||||
mutableStateOf(this)
|
||||
}.apply {
|
||||
if (value != this@interpolate) previousScale = when {
|
||||
interpolation == 1f -> value
|
||||
else -> CapturedContentScale(
|
||||
capturedInterpolation = interpolation,
|
||||
previousScale = previousScale,
|
||||
currentScale = value
|
||||
)
|
||||
}.also { interpolation = 0f }
|
||||
value = this@interpolate
|
||||
}
|
||||
|
||||
LaunchedEffect(currentScale) {
|
||||
animate(
|
||||
initialValue = 0f,
|
||||
targetValue = 1f,
|
||||
animationSpec = spring(
|
||||
stiffness = Spring.StiffnessMedium
|
||||
),
|
||||
block = { progress, _ ->
|
||||
interpolation = progress
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return remember {
|
||||
object : ContentScale {
|
||||
override fun computeScaleFactor(
|
||||
srcSize: Size,
|
||||
dstSize: Size
|
||||
): ScaleFactor {
|
||||
val start = previousScale.computeScaleFactor(
|
||||
srcSize = srcSize,
|
||||
dstSize = dstSize
|
||||
)
|
||||
val stop = currentScale.computeScaleFactor(
|
||||
srcSize = srcSize,
|
||||
dstSize = dstSize
|
||||
)
|
||||
return if (start == stop) stop
|
||||
else lerp(
|
||||
start = start,
|
||||
stop = stop,
|
||||
fraction = interpolation
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CapturedContentScale(
|
||||
private val capturedInterpolation: Float,
|
||||
private val previousScale: ContentScale,
|
||||
private val currentScale: ContentScale,
|
||||
) : ContentScale {
|
||||
|
||||
override fun computeScaleFactor(
|
||||
srcSize: Size,
|
||||
dstSize: Size
|
||||
): ScaleFactor = lerp(
|
||||
start = previousScale.computeScaleFactor(
|
||||
srcSize = srcSize,
|
||||
dstSize = dstSize
|
||||
),
|
||||
stop = currentScale.computeScaleFactor(
|
||||
srcSize = srcSize,
|
||||
dstSize = dstSize
|
||||
),
|
||||
fraction = capturedInterpolation
|
||||
)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user