16
16
17
17
package com.example.compose.jetsurvey.survey
18
18
19
+ import androidx.compose.animation.AnimatedContent
20
+ import androidx.compose.animation.AnimatedContentScope
21
+ import androidx.compose.animation.ExperimentalAnimationApi
22
+ import androidx.compose.animation.core.TweenSpec
19
23
import androidx.compose.animation.core.animateFloatAsState
24
+ import androidx.compose.animation.core.tween
25
+ import androidx.compose.animation.with
20
26
import androidx.compose.foundation.layout.Box
21
27
import androidx.compose.foundation.layout.Column
22
28
import androidx.compose.foundation.layout.Row
@@ -51,11 +57,15 @@ import androidx.compose.ui.res.stringResource
51
57
import androidx.compose.ui.text.buildAnnotatedString
52
58
import androidx.compose.ui.text.font.FontWeight
53
59
import androidx.compose.ui.text.withStyle
60
+ import androidx.compose.ui.unit.IntOffset
54
61
import androidx.compose.ui.unit.dp
55
62
import com.example.compose.jetsurvey.R
56
63
import com.example.compose.jetsurvey.theme.progressIndicatorBackground
57
64
import com.example.compose.jetsurvey.util.supportWideScreen
58
65
66
+ private const val CONTENT_ANIMATION_DURATION = 500
67
+
68
+ @OptIn(ExperimentalAnimationApi ::class )
59
69
@Composable
60
70
fun SurveyQuestionsScreen (
61
71
questions : SurveyState .Questions ,
@@ -79,22 +89,49 @@ fun SurveyQuestionsScreen(
79
89
)
80
90
},
81
91
content = { innerPadding ->
82
- Question (
83
- question = questionState.question,
84
- answer = questionState.answer,
85
- shouldAskPermissions = shouldAskPermissions,
86
- onAnswer = {
87
- if (it !is Answer .PermissionsDenied ) {
88
- questionState.answer = it
89
- }
90
- questionState.enableNext = true
91
- },
92
- onAction = onAction,
93
- onDoNotAskForPermissions = onDoNotAskForPermissions,
94
- modifier = Modifier
95
- .fillMaxSize()
96
- .padding(innerPadding)
97
- )
92
+ AnimatedContent (
93
+ targetState = questionState,
94
+ transitionSpec = {
95
+ val animationSpec: TweenSpec <IntOffset > = tween(CONTENT_ANIMATION_DURATION )
96
+ val direction =
97
+ if (targetState.questionIndex > initialState.questionIndex) {
98
+ // Going forwards in the survey: Set the initial offset to start
99
+ // at the size of the content so it slides in from right to left, and
100
+ // slides out from the left of the screen to -fullWidth
101
+ AnimatedContentScope .SlideDirection .Left
102
+ } else {
103
+ // Going back to the previous question in the set, we do the same
104
+ // transition as above, but with different offsets - the inverse of
105
+ // above, negative fullWidth to enter, and fullWidth to exit.
106
+ AnimatedContentScope .SlideDirection .Right
107
+ }
108
+ slideIntoContainer(
109
+ towards = direction,
110
+ animationSpec = animationSpec
111
+ ) with
112
+ slideOutOfContainer(
113
+ towards = direction,
114
+ animationSpec = animationSpec
115
+ )
116
+ }
117
+ ) { targetState ->
118
+ Question (
119
+ question = targetState.question,
120
+ answer = targetState.answer,
121
+ shouldAskPermissions = shouldAskPermissions,
122
+ onAnswer = {
123
+ if (it !is Answer .PermissionsDenied ) {
124
+ targetState.answer = it
125
+ }
126
+ targetState.enableNext = true
127
+ },
128
+ onAction = onAction,
129
+ onDoNotAskForPermissions = onDoNotAskForPermissions,
130
+ modifier = Modifier
131
+ .fillMaxSize()
132
+ .padding(innerPadding)
133
+ )
134
+ }
98
135
},
99
136
bottomBar = {
100
137
SurveyBottomBar (
0 commit comments