Устранение эффекта мерцания при вращательной анимации элементов спискаAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Устранение эффекта мерцания при вращательной анимации элементов списка

Сообщение Anonymous »

Я работаю со списком из трех элементов, скажем, [A, B, C], и пытаюсь создать с их помощью анимацию вращения. Последовательность этой анимации будет такой: AB, BC, CA, AB и т. д., повторяясь бесконечно. Список также может содержать n объектов, и я хочу, чтобы он вращался бесконечно.
Однако я столкнулся с проблемой обеспечения плавного перехода между элементами. Кажется, наблюдается заметный эффект «мигания», нарушающий плавность анимации. Мне нужен совет, как устранить эту проблему, или предложения по альтернативным методам достижения того же эффекта.
Желаемый эффект, к которому я стремлюсь, показан ниже. Но при наблюдении вы можете заметить, что анимация не является непрерывной и возникает определенный эффект «мигания».
[img]https://i. sstatic.net/mLvXWuQD.gif[/img]

@Composable
fun FollowEventCardHome() {
val data = "{...}"
val eventData = Gson().fromJson(data, EventData::class.java)
var currentEvent by remember { mutableStateOf(eventData.events?.getOrNull(0)) }
var nextEvent by remember { mutableStateOf(eventData.events?.getOrNull(1)) }
var currentIndex by remember { mutableIntStateOf(0) }
var isAnimate by remember { mutableStateOf(true) }

val configuration = LocalConfiguration.current
val cardWidth = configuration.screenWidthDp.dp - 55.dp

if (isAnimate) {
StartEndInfo(
nextEvent = nextEvent,
currentEvent = currentEvent,
isAnimate = true,
isAnimationFinished = {
isAnimate = false
if (eventData.events?.size!! > 1) {
if (currentIndex == eventData.events?.size!! - 1) {
currentIndex = 0
} else {
currentIndex++
}
}
currentEvent = eventData.events?.getOrNull(currentIndex)
nextEvent = if (currentIndex < eventData.events?.size!!) {
eventData.events?.getOrNull(0)
} else {
eventData.events?.getOrNull(currentIndex + 1)
}
}
)
}

if(!isAnimate){
StartEndInfo(
nextEvent = nextEvent,
currentEvent = currentEvent,
isAnimate = true,
isAnimationFinished = {
isAnimate = true
if (eventData.events?.size!! > 1) {
if (currentIndex == eventData.events?.size!! - 1) {
currentIndex = 0
} else {
currentIndex++
}
}
currentEvent = eventData.events?.getOrNull(currentIndex)
nextEvent = if (currentIndex < eventData.events?.size!!) {
eventData.events?.getOrNull(0)
} else {
eventData.events?.getOrNull(currentIndex + 1)
}
}
)
}
}

@Composable
fun StartEndInfo(
nextEvent: Event? = null,
currentEvent: Event? = null,
isAnimate: Boolean,
isAnimationFinished: () -> Unit
) {
Row(
modifier = Modifier
.padding(
start = 16.dp,
bottom = 16.dp
)
.fillMaxWidth()
) {
Column(modifier = Modifier.fillMaxSize()) {
StartEndWithProgress(
nextEvent = nextEvent,
currentEvent = currentEvent,
isAnimate = isAnimate,
isAnimationFinished = isAnimationFinished
)
}
}
}

@Composable
fun StartEndWithProgress(
nextEvent: Event?,
currentEvent: Event?,
isAnimate: Boolean,
isAnimationFinished: () -> Unit
) {
val scalePreviousEvent = remember { Animatable(1f) }
val scaleCurrentEvent = remember { Animatable(0f ) }

LaunchedEffect(isAnimate) {
scalePreviousEvent.animateTo(
targetValue = 0f,
animationSpec = tween(durationMillis = 4000)
)
}

LaunchedEffect(key1 = isAnimate) {
scaleCurrentEvent.animateTo(
targetValue = 1f,
animationSpec = tween(durationMillis = 4000)
)
}

if(isAnimate && scalePreviousEvent.value == 0f || !isAnimate && scalePreviousEvent.value == 1f){
isAnimationFinished()
}

Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 30.dp)
.padding(top = 150.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Box {
currentEvent?.start?.locationCode.let {
Text(
text = currentEvent?.start?.locationCode ?: "",
fontSize = 20.sp,
modifier = Modifier.graphicsLayer {
scaleX = 1f
scaleY = if (isAnimate) {
scaleCurrentEvent.value
} else 1f
transformOrigin = TransformOrigin(0.5f, 1f)
}
)
Text(
text = nextEvent?.start?.locationCode ?: "",
fontSize = 20.sp,
modifier = Modifier.graphicsLayer {
scaleX = 1f
scaleY = if (isAnimate) {
scalePreviousEvent.value
} else 0f
transformOrigin = TransformOrigin(0.5f, 0f)
}
)
}
}
Box {
currentEvent?.end?.locationCode.let {
Text(
text = currentEvent?.end?.locationCode ?: "",
fontSize = 20.sp,
modifier = Modifier.graphicsLayer {
scaleX = 1f
scaleY = if (isAnimate) { scaleCurrentEvent.value } else 1f
transformOrigin = TransformOrigin(0.5f, 1f)
}
)
}
Text(
text = nextEvent?.end?.locationCode ?: "",
fontSize = 20.sp,
modifier = Modifier.graphicsLayer {
scaleX = 1f
scaleY = if (isAnimate) {
scalePreviousEvent.value
} else 0f
transformOrigin = TransformOrigin(0.5f, 0f)
}
)
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/787 ... t-elements
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»