中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Jetpack?Compose怎么實現動畫效果

發布時間:2022-02-28 09:18:12 來源:億速云 閱讀:392 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關Jetpack Compose怎么實現動畫效果,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

概述

compose 為支持動畫提供了大量的 api,通過這些 api 我們可以輕松實現動畫效果

ps:這些 api 的原理與 Flutter 很接近,與原生的 api 相去甚遠

你可以提前看看用 compose 實現的一個放大縮小動畫,總的來說還是比較流暢:

Jetpack?Compose怎么實現動畫效果

低級別動畫 API

animate*AsState

所能處理屬性的種類:Float、Color、Dp、Size、Bounds、Offset、Rect、Int、IntOffset 和 IntSize

通過 animate*AsState 我們可以實現單一屬性的動畫效果,我們只需要提供目標值就可以自動從當前進度動畫過渡到目標值

實現放大動畫

1.代碼

@Composable
fun animSize() {
    val enable = remember {
        mutableStateOf(true)
    }
    val size =
        animateSizeAsState(targetValue = if (enable.value) Size(50f, 50f) else Size(300f, 300f))
    Column(
        modifier = Modifier.fillMaxSize(1f),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Image(
            modifier = Modifier
                .size(size.value.width.dp, size.value.height.dp)
                .clickable {
                    enable.value = !enable.value
                },
            painter = painterResource(id = R.drawable.apple),
            contentDescription = ""
        )
    }
}

2.實現效果

Jetpack?Compose怎么實現動畫效果

實現顏色變化動畫

1.代碼

@Composable
fun animColor() {
    val enable = remember {
        mutableStateOf(true)
    }
    val colors = animateColorAsState(targetValue = if (enable.value) Color.Green else Color.Red)
    val size = animateIntSizeAsState(
        targetValue = if (enable.value) IntSize(100, 100) else IntSize(
            300,
            300
        )
    )
    Column(
        modifier = Modifier.fillMaxWidth(1f),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Box(
            modifier = Modifier
                .size(size.value.width.dp, size.value.height.dp)
                .height(400.dp)
                .background(
                    color = colors.value,
                    shape = if (enable.value) RectangleShape else CircleShape
                )
        ) {

        }
    }
}

2.效果

Jetpack?Compose怎么實現動畫效果

使用 Animatable 實現顏色變化效果

Animatable 是一個值容器,我們可以通過調用 animateTo 實現動畫效果。動畫執行過程中如果再次開啟動畫會中斷當前動畫。

Animatable 動畫執行過程中值的變化是在協程中執行的,所以 animateTo 是一個掛起操作

1.代碼

@Composable
fun animChangeColor() {
    val color = remember {
        Animatable(Color.Red)
    }
    val state = remember {
        mutableStateOf(true)
    }
    LaunchedEffect(state.value) {
        color.animateTo(if (state.value) Color.Red else Color.Magenta)
    }
    Box(Modifier.fillMaxSize(1f), contentAlignment = Alignment.Center) {
        Box(
            modifier = Modifier
                .background(color.value, shape = RoundedCornerShape(30.dp))
                .size(200.dp)
                .clickable {
                    state.value = !state.value
                }, contentAlignment = Alignment.Center
        ) {
            Text(
                text = "顏色動畫",
                style = TextStyle(color = Color.White, fontSize = 40.sp)
            )
        }
    }
}

2.效果

Jetpack?Compose怎么實現動畫效果

使用 updateTransition 實現顏色和圓角動畫

使用 updateTransition 可以實現多個動畫組合的效果。

例如:我們可以在動畫執行過程中同時執行大小和顏色變化效果

本例中我們定義了一個枚舉用來控制動畫,枚舉可以定義多個,分別用來對應動畫的多個狀態

1.代碼

@Composable
fun animupdateTransition() {
    var state by remember {
        mutableStateOf(BoxState.Collapsed)
    }
    val transition = updateTransition(targetState = state, label = "")

    val round = transition.animateDp(label = "") {
        when (it) {
            BoxState.Collapsed -> 40.dp
            BoxState.Expanded -> 100.dp
        }
    }
    val color = transition.animateColor(label = "") {
        when (it) {
            BoxState.Collapsed -> Color.Red
            BoxState.Expanded -> Color.Green
        }
    }
    Box(Modifier.fillMaxSize(1f),contentAlignment = Alignment.Center) {
        Box(
            modifier = Modifier
                .size(300.dp)
                .background(
                    color.value,
                    shape = RoundedCornerShape(corner = CornerSize(round.value))
                )
                .clickable {
                    state =
                        if (state == BoxState.Collapsed) BoxState.Expanded else BoxState.Collapsed
                },contentAlignment = Alignment.Center
        ) {
            Text(text = "點擊開始動畫",style = TextStyle(color = Color.White,fontSize = 20.sp))
        }
    }
}
private enum class BoxState {
    Collapsed,
    Expanded
}

2.效果

Jetpack?Compose怎么實現動畫效果

rememberInfiniteTransition

rememberInfiniteTransition 的使用和 updateTransition 基本一樣,不同的是 rememberInfiniteTransition 的動畫一旦開始便會一直反復運行下去,只有被移除動畫才能結束

1.代碼

@Composable
fun rememberInfiniteTransition1() {
    val infiniteTransition = rememberInfiniteTransition()
    val color by infiniteTransition.animateColor(
        initialValue = Color.Red,
        targetValue = Color.Green,
        animationSpec = infiniteRepeatable(
            animation = tween(1000, easing = LinearEasing),
            repeatMode = RepeatMode.Reverse
        )
    )

    Box(Modifier.fillMaxSize(1f), contentAlignment = Alignment.Center) {
        Box(
            Modifier
                .fillMaxSize(0.8f)
                .background(color),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = "公眾號:安安安安卓 原創,禁抄襲",
                style = TextStyle(color = Color.White, fontSize = 30.sp)
            )
        }
    }
}

2.效果

Jetpack?Compose怎么實現動畫效果

TargetBasedAnimation

TargetBasedAnimation 可以控制動畫的執行時間,還可以延遲一段時間再開啟動畫。

1.代碼

@Composable
fun animTargetBasedAnimation() {
    var state by remember {
        mutableStateOf(0)
    }
    val anim = remember {
        TargetBasedAnimation(
            animationSpec = tween(2000),
            typeConverter = Float.VectorConverter,
            initialValue = 100f,
            targetValue = 300f
        )
    }
    var playTime by remember { mutableStateOf(0L) }
    var animationValue by remember {
        mutableStateOf(0)
    }

    LaunchedEffect(state) {
        val startTime = withFrameNanos { it }
        println("進入協程:")
        do {
            playTime = withFrameNanos { it } - startTime
            animationValue = anim.getValueFromNanos(playTime).toInt()
        } while (!anim.isFinishedFromNanos(playTime))

    }
    Box(modifier = Modifier.fillMaxSize(1f),contentAlignment = Alignment.Center) {
        Box(modifier = Modifier
            .size(animationValue.dp)
            .background(Color.Red,shape = RoundedCornerShape(animationValue/5))
            .clickable {
                state++
            },contentAlignment = Alignment.Center) {
            Text(text = animationValue.toString(),style = TextStyle(color = Color.White,fontSize = (animationValue/5).sp))
        }
    }
}

2.效果

Jetpack?Compose怎么實現動畫效果

自定義動畫

AnimationSpec

AnimationSpec 可以自定義動畫的行為,效果類似于原生動畫中的估值器。

SpringSpec 彈簧效果

1.代碼

@Composable
fun animSpring() {
    val state = remember {
        mutableStateOf(true)
    }
    var value = animateIntAsState(
        targetValue = if (state.value) 300 else 100,
        animationSpec = spring(
            dampingRatio = Spring.DampingRatioHighBouncy,
            stiffness = Spring.StiffnessVeryLow
        )
    )

    Box(
        Modifier
            .fillMaxSize(1f)
            .padding(start = 30.dp), contentAlignment = Alignment.CenterStart
    ) {
        Box(
            Modifier
                .width(value.value.dp)
                .height(80.dp)
                .background(Color.Red, RoundedCornerShape(topEnd = 30.dp, bottomEnd = 30.dp))
                .clickable {
                    state.value = !state.value
                }, contentAlignment = Alignment.CenterStart
        ) {
            Text(text = "哈哈哈", style = TextStyle(color = Color.White, fontSize = 20.sp))
        }
    }
}

2.效果

Jetpack?Compose怎么實現動畫效果

TweenSpec 動畫時間可控

1.代碼

@Composable
fun animTweenSpec() {
    val state = remember {
        mutableStateOf(true)
    }
    val value = animateIntAsState(
        targetValue = if (state.value) 300 else 100,
        animationSpec = tween(
            durationMillis = 1500,
            delayMillis = 200,
            easing = LinearEasing
        )
    )

    Box(
        Modifier
            .fillMaxSize(1f)
            .padding(start = 50.dp), contentAlignment = Alignment.CenterStart
    ) {
        Box(
            Modifier
                .width(value.value.dp)
                .height(100.dp)
                .background(Color.Red, RoundedCornerShape(topEnd = 30.dp, bottomEnd = 30.dp))
                .clickable {
                    state.value = !state.value
                }
        ) {

        }
    }

}

2.效果

Jetpack?Compose怎么實現動畫效果

FrameSpec

1.代碼

@Composable
fun animkeyframesSpec() {
    var state by remember {
        mutableStateOf(true)
    }
    val value by animateIntAsState(
        targetValue = if (state) 300 else 100,
        animationSpec = keyframes {
            durationMillis = 2000
            0 at 700 with LinearOutSlowInEasing
            700 at 1400 with FastOutLinearInEasing
            1400 at 2000
        })

    Box(Modifier.fillMaxSize(1f), contentAlignment = Alignment.CenterStart) {
        Box(
            Modifier
                .width(value.dp)
                .height(100.dp)
                .background(Color.Red, RoundedCornerShape(topEnd = 30.dp, bottomEnd = 30.dp))
                .clickable {
                    state = !state
                }
        ) {

        }
    }
}

2.效果

Jetpack?Compose怎么實現動畫效果

RepeatableSpec 實現有限次數的重復動畫

執行有限次數動畫后自動停止

1.代碼

@Composable
fun animrepeatableSpec() {
    var state by remember {
        mutableStateOf(true)
    }
    val value by animateIntAsState(
        targetValue = if (state) 300 else 100,
        animationSpec = repeatable(
            iterations = 5,//動畫重復執行的次數,設置多少就執行多少次
            animation = tween(durationMillis = 1000),
            repeatMode = RepeatMode.Reverse
        )
    )
    Box(
        Modifier
            .fillMaxSize(1f)
            .padding(start = 30.dp), contentAlignment = Alignment.CenterStart) {
        Box(
            Modifier
                .width(value.dp)
                .height(100.dp)
                .background(Color.Red, RoundedCornerShape(topEnd = 30.dp, bottomEnd = 30.dp))
                .clickable {
                    state = !state
                }
        ) {

        }
    }
}

2.效果

代碼中設置了重復 5 次,所以反復執行五次后動畫結束

Jetpack?Compose怎么實現動畫效果

InfiniteRepeatableSpec 無限次數執行動畫

動畫會無限次的執行下去,直到視圖被移除

1.代碼

@Composable
fun animinfiniteRepeatableSpec() {
    var state by remember {
        mutableStateOf(true)
    }
    val value by animateIntAsState(
        targetValue = if (state) 300 else 100,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis = 1000),
            repeatMode = RepeatMode.Reverse
        )
    )
    Box(
        Modifier
            .fillMaxSize(1f)
            .padding(start = 30.dp), contentAlignment = Alignment.CenterStart) {
        Box(
            Modifier
                .width(value.dp)
                .height(100.dp)
                .background(Color.Red, RoundedCornerShape(topEnd = 30.dp, bottomEnd = 30.dp))
                .clickable {
                    state = !state
                }
        ) {
            Text(text = "公眾號:安安安安卓 原創,禁轉載")
        }
    }
}

2.效果

Jetpack?Compose怎么實現動畫效果

Easing

Easing 類似于我們原生動畫中的差值器

有以下幾種選擇:

  • FastOutSlowInEasing

  • LinearOutSlowInEasing

  • FastOutLinearInEasing

  • LinearEasing

  • CubicBezierEasing

這幾種實現的效果和 android 原生實現的動畫差值器差距很大,甚至看不出有啥效果,所以代碼我就不放了。有清楚原因的讀者可以聯系我

實現效果:

Jetpack?Compose怎么實現動畫效果

AnimationVector

大多數 Compose 動畫 API 都支持將 Float、Color、Dp 以及其他基本數據類型作為開箱即用的動畫值,但有時我們需要為其他數據類型(包括我們的自定義類型)添加動畫效果

本例中實現顏色和大小的變換動畫

代碼中我們定義了一個 AnimSize 類,類中的第一個參數是顏色數據,第二個參數是尺寸數據。動畫執行過程中會同事改變顏色和控件尺寸效果。

1.代碼

@Composable
fun animAnimationVector() {
    var state by remember {
        mutableStateOf(true)
    }
    val value by animateValueAsState(
        targetValue = if (state) AnimSize(0xffff5500, 100f) else AnimSize(0xff00ff00, 300f),
        typeConverter = TwoWayConverter(
            convertToVector = {
//                AnimationVector2D(target.color.toFloat(), target.size)
                AnimationVector2D(it.color.toFloat(), it.size)
            },
            convertFromVector = {
                AnimSize(it.v1.toLong(), it.v2)
            }
        )
    )
    println("顏色:${value.color}")
    Box(modifier = Modifier.fillMaxSize(1f).padding(30.dp), contentAlignment = Alignment.Center) {
        Box(
            modifier = Modifier
                .size(value.size.dp)
//                .size(300.dp)
                .background(Color(value.color), RoundedCornerShape(30.dp))
                .clickable {
                    state = !state
                }
        ) {

        }
    }
}

data class AnimSize(val color: Long, val size: Float)

2.效果

缺點是執行顏色變化過程中有閃爍

Jetpack?Compose怎么實現動畫效果

高級動畫

高級動畫一般指封裝性較高的動畫,使用較為簡單,主要有以下三種:

因高級動畫效果不明顯,gif 很難展現出效果,所以這里不放代碼和效果圖了

  1. AnimatedVisibility

  2. animateContentSize

  3. Crossfade

關于“Jetpack Compose怎么實現動畫效果”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

高安市| 舒兰市| 芷江| 长海县| 庆云县| 长乐市| 星子县| 淮安市| 巴青县| 乐平市| 昌平区| 神农架林区| 高安市| 田东县| 乌拉特前旗| 克拉玛依市| 卢氏县| 略阳县| 柯坪县| 祁门县| 筠连县| 大方县| 丹凤县| 九龙城区| 三门县| 湘阴县| 鄢陵县| 郴州市| 江山市| 应城市| 高淳县| 新昌县| 霍山县| 景东| 崇州市| 益阳市| 海城市| 都兰县| 长乐市| 昌都县| 嵊泗县|