当前位置:网站首页>Principle of efficient animation Implementation-A preliminary exploration of jetpack compose

Principle of efficient animation Implementation-A preliminary exploration of jetpack compose

2022-06-24 03:04:00 2020labs assistant

One 、 brief introduction

Jetpack Compose yes Google New for building native interfaces Android tool kit , It simplifies and speeds up Android Interface development on .Jetpack Compose It's a declarative one UI frame , With the introduction of the framework , Mark the Android Start embracing Shengming UI Development .Jetpack Compose There are many advantages : The code is more concise and intuitive 、 Application development efficiency has been significantly improved 、Kotlin API Intuitive function 、 Preview tools are powerful and so on .

Two 、 development environment

In order to get a better development experience , Here's what I'm using Android Studio Canary edition , This eliminates the need to configure some settings and dependencies .( Download address

Open the project , newly build Empty Compose activity Template , You should pay attention to the... In the root directory build.gradle, Dependent dependency com.android.tools.build and org.jetbrains.kotlin The version needs to correspond to , Otherwise, errors may occur , What we use here is :

dependencies {
	classpath "com.android.tools.build:gradle:7.0.0-alpha15"
	classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.30"
}

This completes the creation of the project .

3、 ... and 、Jetpack Compose Animation

Jetpack Compose Provides some powerful and scalable API, It can be used to easily realize various animation effects in the application interface . The following will describe Jetpack Compose Animations The common methods of .

3.1 State driven animation :State

Jetpack Compose Animation is through monitoring the State , That is, monitor the change of status value , send UI Can realize automatic update . Composable functions can use remember perhaps mutableStateOf Listen for changes in status values . If the state value is constant ,remember The function maintains this value every time it is recombined ; If the state is variable , It triggers reorganization when the value changes ,mutableStateOf Will get a MutableState object , It is an observable type .

This reorganization is the key to creating state driven animation . Use reorganization , They are triggered by any change in the state of composable components .Compose Animation is made up of State Driven , Animation related API It's also easier to get started , It's easier to create beautiful declarative animation .

3.2 Visibility animation : AnimatedVisibility

First, let's look at the function definition :

@ExperimentalAnimationApi
@Composable
fun AnimatedVisibility(
    visible: Boolean,
    modifier: Modifier = Modifier,
    enter: EnterTransition = fadeIn() + expandIn(),
    exit: ExitTransition = shrinkOut() + fadeOut(),
    initiallyVisible: Boolean = visible,
    content: @Composable () -> Unit
) {
    AnimatedVisibilityImpl(visible, modifier, enter, exit, initiallyVisible, content)
}

You can see that the default animation is fade in and zoom in 、 Fade shrink , In practice, various dynamic effects are realized by passing in different functions .

As the visible value changes ,AnimatedVisibility You can animate the appearance and disappearance of its content . The following code , You can click Button, Control the appearance and disappearance of pictures .

@Composable
fun AinmationDemo() {

    //AnimatedVisibility  Visible animation 
    var visible by remember { mutableStateOf(true) }

    Column(
        Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
        Arrangement.Top,
        Alignment.CenterHorizontally
    ) {
        Button(
            onClick = { visible = !visible }
        ) {
            Text(text = if (visible) "Hide" else "Show")
        }

        Spacer(Modifier.height(16.dp))

        AnimatedVisibility(
            visible = visible,
            enter = slideInVertically() + fadeIn(),
            exit = slideOutVertically() + fadeOut()
        ) {
            Image(
                painter = painterResource(id = R.drawable.pikaqiu),
                contentDescription = null,
                Modifier.fillMaxSize()
            )
        }
    }
}

By monitoring visible The change of , It can realize the visibility animation of pictures , The effect is shown in the small picture ;

3.3 Layout size animation :AnimateContentSize

Let's first look at the definition of the function :

fun Modifier.animateContentSize(
    animationSpec: FiniteAnimationSpec<IntSize> = spring(),
    finishedListener: ((initialValue: IntSize, targetValue: IntSize) -> Unit)? = null
)

You can set the animation speed and listening value for layout size animation .

From the definition of the function, we can see that the function is essentially Modefier An extension function of . You can go through the variables size Monitor the change of state to realize the animation effect of layout size , The code is as follows :

// Zoom in and out of the animation  animateContentSize
    var size by remember { mutableStateOf(Size(300F, 300F)) }

    Column(
        Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
        Arrangement.Top,
        Alignment.CenterHorizontally
    ) {
        Spacer(Modifier.height(16.dp))

        Button(
            onClick = {
                size = if (size.height == 300F) {
                    Size(500F, 500F)
                } else {
                    Size(300F, 300F)
                }
            }
        ) {
            Text(if (size.height == 300F) "Shrink" else "Expand")
        }
        Spacer(Modifier.height(16.dp))

        Box(
            Modifier
                .animateContentSize()
        ) {
            Image(
                painter = painterResource(id = R.drawable.pikaqiu),
                contentDescription = null,
                Modifier
                    .animateContentSize()
                    .size(size = size.height.dp)
            )
        }
} // Zoom in and out of the animation  animateContentSize    var size by remember { mutableStateOf(Size(300F, 300F)) }    Column(        Modifier            .fillMaxWidth()            .fillMaxHeight(),        Arrangement.Top,        Alignment.CenterHorizontally    ) {        Spacer(Modifier.height(16.dp))        Button(            onClick = {                size = if (size.height == 300F) {                    Size(500F, 500F)                } else {                    Size(300F, 300F)                }            }        ) {            Text(if (size.height == 300F) "Shrink" else "Expand")        }        Spacer(Modifier.height(16.dp))        Box(            Modifier                .animateContentSize()        ) {            Image(                painter = painterResource(id = R.drawable.pikaqiu),                contentDescription = null,                Modifier                    .animateContentSize()                    .size(size = size.height.dp)            )        }}

adopt Button Click on , monitor size Change in value , utilize animateContentSize() animating , The specific dynamic effect is shown in the figure below :

3.4 Layout switch animation : Crossfade

Crossfade You can monitor the change of status value , Use fade in and fade out animation to add animation effects between two layouts , The function itself is a Composable, The code is as follows :

//Crossfade  Fade in and out animation 
    var fadeStatus by remember { mutableStateOf(true) }

    Column(
        Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
        Arrangement.Top,
        Alignment.CenterHorizontally
    ) {
        Button(
            onClick = { fadeStatus = !fadeStatus }
        ) {
            Text(text = if (fadeStatus) "Fade In" else "Fade Out")
        }

        Spacer(Modifier.height(16.dp))

        Crossfade(targetState = fadeStatus, animationSpec = tween(3000)) { screen ->
            when (screen) {
                true -> Image(
                    painter = painterResource(id = R.drawable.pikaqiu),
                    contentDescription = null,
                    Modifier
                        .animateContentSize()
                        .size(300.dp)
                )
                false -> Image(
                    painter = painterResource(id = R.drawable.pikaqiu2),
                    contentDescription = null,
                    Modifier
                        .animateContentSize()
                        .size(300.dp)
                )
            }
        }

    }

Also by listening fadeStatus Value , Realize the animation of layout switching , The specific dynamic effect is shown in the figure :

3.5 Single value animation :animate*AsState

Add animation effects to individual values . Just provide the end value ( Or target value ), The API The animation will be played from the current value to the specified value .

Jetpack Compose There are many built-in functions , You can animate different types of data , for example :animateColorAsState、animateDpAsState、animateOffsetAsState etc. , Here we will introduce animateFooAsState Use , The code is as follows :

//animate*AsState  Add animation to a single value 
    var transparent by remember { mutableStateOf(true) }
    val alpha: Float by animateFloatAsState(if (transparent) 1f else 0.5f)

    Column(
        Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
        Arrangement.Top,
        Alignment.CenterHorizontally
    ) {
        Button(
            onClick = { transparent = !transparent }
        ) {
            Text(if (transparent) "Light" else "Dark")
        }

        Spacer(Modifier.height(16.dp))

        Box {

            Image(
                painter = painterResource(id = R.drawable.pikaqiu),
                contentDescription = null,
                Modifier
                    .animateContentSize()
                    .graphicsLayer(alpha = alpha)
                    .size(300.dp)
            )
        }
}

The animation effect is shown in the figure below :

3.6 Combination animation :updateTransition

Transition You can track one or more animations at the same time , And synchronize these animations between multiple states . The specific code is as follows :

var imagePosition by remember { mutableStateOf(ImagePosition.TopLeft) }

    Column(
        Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
        Arrangement.Top,
        Alignment.CenterHorizontally
    ) {
        Spacer(Modifier.height(16.dp))

        val transition = updateTransition(targetState = imagePosition, label = "")
        val boxOffset by transition.animateOffset(label = "") { position ->
            when (position) {
                ImagePosition.TopLeft -> Offset(-60F, 0F)
                ImagePosition.BottomRight -> Offset(60F, 120F)
                ImagePosition.TopRight -> Offset(60F, 0F)
                ImagePosition.BottomLeft -> Offset(-60F, 120F)
            }
        }
        Button(onClick = {
            imagePosition = ChangePosition(imagePosition)
        }) {
            Text("Change position")
        }
        Box {

            Image(
                painter = painterResource(id = R.drawable.pikaqiu),
                contentDescription = null,
                Modifier
                    .offset(boxOffset.x.dp, boxOffset.y.dp)
                    .animateContentSize()
                    .size(300.dp)
            )
        }
}

among ,ImagePosition、ChangePosition They are the defined enumeration classes 、 Custom function .

enum class ImagePosition {
    TopRight,
    TopLeft,
    BottomRight,
    BottomLeft
}

fun ChangePosition(position: ImagePosition) =
    when (position) {
        ImagePosition.TopLeft -> ImagePosition.BottomRight
        ImagePosition.BottomRight -> ImagePosition.TopRight
        ImagePosition.TopRight -> ImagePosition.BottomLeft
        ImagePosition.BottomLeft -> ImagePosition.TopLeft
    }

The animation is shown in the figure below :

Four 、 Conclusion

Jetpack Compose The animation has been simplified to the point where we only need to create declarative code in our composable functions , Just write hope UI How to animate , The rest is made up of Compose management . Last , This is also Jetpack Compose Main objectives of : Create a declarative UI Toolkit to accelerate application development and improve code readability and logic .

Jetpack Compose Provided declarative UI tool kit , It can achieve more functions with less code , And the readability and logic of the code are also greatly improved .

author :vivo Internet game client team -Ke Jie

原网站

版权声明
本文为[2020labs assistant]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/10/20211019184103640o.html