android - 列数更改时动画回收器 View 网格

标签 android android-recyclerview android-animation

我正在使用 RecyclerViewGridLayoutManager。用户可以在 2 和 4 之间切换跨度计数,这将生成一个动画,将每个单元格的内置翻译动画运行到它的新位置。到目前为止我一直在使用的代码是:

TransitionManager.beginDelayedTransition(moviesGridRecycler);
gridLayoutManager.setSpanCount(NEW_SPAN_COUNT);
adapter.notifyDataSetChanged();

enter image description here

这对我来说一直很好,但现在我需要为每个跨度计数设置不同的布局。为了支持这一点,我在 RecyclerView 中有 2 种 View 类型,并且由于在移动到新的跨度计数时 View 类型发生了变化,RecyclerView 无法看到它是“相同”的内容,并且不运行默认的翻译动画。

enter image description here

如果我启用布局转换,我将获得 View 进入动画而不是 View 位置更改动画。两个跨度计数的单元格 View 的宽度和高度为 match_parentwrap_content

作为替代方案,我尝试将所有新 View 类型一起删除,只使用一种 View 类型。我有一个 FrameLayout,它包含两个跨度计数的 View 。在 onBindViewHolder() 中,我只是切换 subview 的可见性。这也会导致没有动画。

我关注了this threadthis one ,但无法解决我的问题。

完整代码:

    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<DummyItem>,
        var span: Int)
    : RecyclerView.Adapter<MyItemRecyclerViewAdapter.ViewHolder>() {


    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
    }
}

最佳答案

我有一个解决你的问题的办法,把你的切换功能改成这样:

  fun onToggle() {
        spanCount = if (spanCount == 2) 4 else 2
        (recyclerView.adapter!! as MyItemRecyclerViewAdapter).apply {
            span = spanCount
            notifyDataSetChanged()
        }
recyclerView.post(object:Runnable {
  public override fun run() {
     TransitionManager.beginDelayedTransition(recyclerView)
        (recyclerView.layoutManager as GridLayoutManager).spanCount = spanCount
  }
})
   }

在上面的代码中,我们首先改变了recyclerView的viewType,然后我们改变了RecyclerView UI Handler Queue上的GridLayoutManager的spanCount,从而实现了两个UI操作的串行。

关于android - 列数更改时动画回收器 View 网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51353595/

相关文章:

android - 回收站 View : item position intent

android - 多个ViewHolder RecycleVIew列表重新排列

android - RecyclerView 用它下面的 View 滑动

java - Android Jsoup Html 解析?

android - Android 中 Webview 的上下滑动动画

android - RecyclerView - Activity 开始时的 SlideIn 动画

android - 将两个动画应用于同一 View ?

android - 更改动画 View 容器的大小

android - 当 Android Activity 的回调在方向更改后变为 null 时,更新回调引用的正确方法是什么

java - 处理各种屏幕尺寸的可绘制对象