title: Animate Recycler View grid when number of columns change
body: <p>I am using a <code>RecyclerView</code> with <code>GridLayoutManager</code>. Users can toggle the span count between 2 and 4, which would result in an animation that runs the inbuilt translate animation for each cell to it's new position. Code I have been using thus far is:</p>
  
  <pre><code>TransitionManager.beginDelayedTransition(moviesGridRecycler);
  gridLayoutManager.setSpanCount(NEW_SPAN_COUNT);
  adapter.notifyDataSetChanged();
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/tR63l.gif" rel="noreferrer"><img src="https://i.stack.imgur.com/tR63l.gif" alt="enter image description here"></a></p>
  
  <p>This has been working fine for me, but now I need to have a different layout for each span count. To support this, I have 2 view types in the <code>RecyclerView</code> and since the view type is changed when moving to a new span count, <code>RecyclerView</code> is unable to see that it's the "same" content, and the default translate animation is not run. </p>
  
  <p><a href="https://i.stack.imgur.com/pIJy1.gif" rel="noreferrer"><img src="https://i.stack.imgur.com/pIJy1.gif" alt="enter image description here"></a></p>
  
  <p>If I enable layout transitions, I get view entry animations and not view position change animations. Cell views for both span count are having a width and height as <code>match_parent</code> and <code>wrap_content</code>.</p>
  
  <p>As an alternative, I tried dropping the new view type all together, and just having one view type. I have a <code>FrameLayout</code>, which holds views for both span counts. In <code>onBindViewHolder()</code>, I simply toggle visibility of child views. This too results in no animations.</p>
  
  <p>I followed <a href="https://stackoverflow.com/questions/35082638/recyclerview-animate-change-of-grid-layout-manager-columns">this thread</a> and <a href="https://stackoverflow.com/questions/26539663/how-do-i-use-a-gridlayoutanimation-in-a-recyclerview">this one</a>, but could not resolve my issue.</p>
  
  <p>Full Code:</p>
  
  <pre><code>    class ItemFragment : Fragment() {
      private var spanCount = 2
      lateinit var recyclerView: RecyclerView
      lateinit var button: Button
  
      override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View? {
          val view = inflater.inflate(R.layout.fragment_item_list, container, false)
          recyclerView = view.findViewById(R.id.listView)
          recyclerView.apply {
              adapter = MyItemRecyclerViewAdapter(DummyContent.ITEMS, spanCount)
              layoutManager = GridLayoutManager(context, spanCount)
              addItemDecoration(RecyclerGridDecoration(context))
          }
          button = view.findViewById(R.id.toggle)
          button.setOnClickListener { onToggle() }
  
          return view
      }
  
      fun onToggle() {
          spanCount = if (spanCount == 2) 4 else 2
          TransitionManager.beginDelayedTransition(recyclerView)
          (recyclerView.layoutManager as GridLayoutManager).spanCount = spanCount
          (recyclerView.adapter!! as MyItemRecyclerViewAdapter).apply {
              span = spanCount
              notifyDataSetChanged()
          }
      }
  
  }
  
  
  
  class MyItemRecyclerViewAdapter(
          private val mValues: List&lt;DummyItem&gt;,
          var span: Int)
      : RecyclerView.Adapter&lt;MyItemRecyclerViewAdapter.ViewHolder&gt;() {
  
  
      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
          if (viewType == 2) {
              val view = LayoutInflater.from(parent.context)
                      .inflate(R.layout.items_two, parent, false)
              return TwoViewHolder(view)
          } else {
              val view = LayoutInflater.from(parent.context)
                      .inflate(R.layout.items_four, parent, false)
              return FourViewHolder(view)
          }
  
      }
  
      override fun onBindViewHolder(holder: ViewHolder, position: Int) {
          val item = mValues[position]
          if (holder is TwoViewHolder) {
              holder.textTwo.text = item.content
          } else if (holder is FourViewHolder) {
              holder.textFour.text = item.content
          }
      }
  
      override fun getItemCount(): Int = mValues.size
  
      abstract inner class ViewHolder(mView: View) : RecyclerView.ViewHolder(mView)
  
      inner class TwoViewHolder(mView: View) : ViewHolder(mView) {
          val image: ImageView = mView.imageTwo
          val textTwo: TextView = mView.textTwo
  
      }
  
      inner class FourViewHolder(mView: View) : ViewHolder(mView) {
          val textFour: TextView = mView.textFour
      }
  
      override fun getItemViewType(position: Int): Int {
          return span
      }
  }
  </code></pre>