MotionLayout Expanding Recycler List View - как сбросить переход
Мне кажется, что я глупый, я хочу использовать MotionLayout на ViewHolder в моем RecyclerView для анимации между двумя состояниями (текущая воспроизводимая песня расширяется, а последняя воспроизводимая песня сокращается) Однако, похоже, что просмотрщик слишком хорош, он просто меняет содержимое, не меняя представления, т.е. когда изменяется текущая воспроизводимая песня, представление уже находится в состоянии "Конец перехода", поэтому мой переход ничего не делает. То же самое, что мой ранее расширенный элемент возвращается в закрытое состояние, поэтому моя анимация ничего не делает.
Итак, хорошо, я подумал, давайте проверим состояние перехода и установим прогресс, но это приведет к тому, что переход не будет запущен, если я установлю прогресс на строку раньше. Я пытался, добавив некоторые задержки, но никаких реальных улучшений,
Я чувствую, что, может быть, я перерабатывал это, или я упускаю что-то фундаментальное о том, как сбросить анимацию с замедленным движением. Любая помощь будет высоко оценена.
override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
if (songs.isNotEmpty() && position < songs.size) {
val current = songs[position]
holder.songName?.text = current.song
holder.albumArt?.setImageResource(current.albumArtId)
holder.artistName?.text = current.artist
var ml = holder.motionLayout
if (current.currentPlaying){
//The view is recycled so its already in the end state... so set it to the start state and animate
if (ml?.progress!! > 0f) {
ml?.progress = 0f //<- This resets the animation state
}
ml?.transitionToEnd() <- but at this point the animation does not work if i have manually set the progress the line above
}else{
if (current.previoussong){
//The view that was last expended is not in the end state, so set it then transation to start
if (ml?.progress!! < 1f) {
ml?.progress = 1f
}
ml?.transitionToStart()
}
}
}
}
1 ответ
Хорошо, если у кого-то есть такая же проблема, я нашел "ответ" на мою дилемму.
Вместо того, чтобы установить прогресс, я явно установил переход, затем попросил его перейти к концу, это работало для расширения.
И чтобы получить сокращенную работу, я должен был создать другой начальный макет с перевернутой сценой движения, затем перейти к концу и установить "previoussong" как другой viewType в моем creatViewHolder
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder {
//Use the int to switch?
val itemView : View = when (viewType) {
TYPEPLAYING -> inflater.inflate(R.layout.list_motion_layout, parent, false)
TYPEUPCOMING -> inflater.inflate(R.layout.list_motion_layout, parent, false)
TYPEPREVIOUS -> inflater.inflate(R.layout.list_motion_layout_shrink, parent, false)
else
-> inflater.inflate(R.layout.footer, parent, false)
}
...
}
override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
if (songs.isNotEmpty() && position < songs.size) {
val current = songs[position]
holder.songName?.text = current.song
holder.albumArt?.setImageResource(current.albumArtId)
holder.artistName?.text = current.artist
var ml = holder.motionLayout
if (current.currentPlaying){
ml?.setTransition(list_motion_layout_start, currentplaying_song)
ml?.transitionToEnd()
}
if (current.previouslyPlaying) {
ml?.setTransition(currentplaying_song, list_motion_layout_start) // Not sure if this is actually required
ml?.transitionToEnd()
}
}
}
В общем, у меня есть работающий адаптер списка расширения / сжатия, использующий motionview, он выглядит довольно хорошо, но, вероятно, есть более приятные способы сделать это, извините, я не могу поделиться какими-либо фотографиями.