1

I feel like I am being silly, I want to use MotionLayout on an ViewHolder within my RecyclerView to animate between two states (the current playing song is expanded, while the last playing song is shrunk) However it seems that the recyclerview is too good, it simply changes the contents without changing the views, i.e. when the current playing song changes, the view is already in the End Transition state, so my transition does nothing. Same my previously expanded item is rebound into the closed state so my animation does nothing.

So Okay i thought lets check the state of the transition and set the progress, but this leads to the transition not running if i set the progress the line before. I have tried, adding in some delays but no real improvement,

I feel like maybe I am over engineering this, or I am missing something fundamental about how to reset motionlayout animations.. Any help will be much appreciated.

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()

                }
            }
        }

    }
AidenFry
  • 248
  • 3
  • 12

1 Answers1

1

Okay incase anyone has the same issue, i found "an" answer to my dilemma.

Insteead of setting the progress, i explicitly set the transition then asked it to transition to end, this worked for expand.

And to get shrink working i had to create a different initial layout with an inverted motionscene, then transition to the end, and set the "previoussong" as a different viewType in my 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()

        }

    }

}

All in all i have a working expand/shrink list adapter using motionview it looks quite nice, but there is probably nicer ways to do this out there ,,, sorry cant share any pics.

AidenFry
  • 248
  • 3
  • 12