android – Animate Recycler在列数更改时查看网格

我正在使用带有GridLayoutManager的RecyclerView.用户可以在2到4之间切换跨度计数,这将导致动画将每个单元格的内置翻译动画运行到其新位置.我到目前为止使用的代码是:
TransitionManager.beginDelayedTransition(moviesGridRecycler);
gridLayoutManager.setSpanCount(NEW_SPAN_COUNT);
adapter.notifyDataSetChanged();

@H_502_5@

这对我来说一直很好,但现在我需要为每个跨度计数设置不同的布局.为了支持这一点,我在RecyclerView中有2种视图类型,并且由于在移动到新的跨度计数时视图类型已更改,因此RecyclerView无法看到它是“相同”内容,并且未运行认的转换动画.@H_502_5@

@H_502_5@

如果我启用布局转换,我会获得视图输入动画,而不是查看位置更改动画.两个跨度计数的单元格视图的宽度和高度为match_parent和wrap_content.@H_502_5@

作为替代方案,我尝试将所有新视图类型放在一起,只有一种视图类型.我有一个FrameLayout,它保存两个跨度计数的视图.在onBindViewHolder()中,我只是切换子视图的可见性.这也导致没有动画.@H_502_5@

我跟着@L_404_2@和this one,但无法解决我的问题.@H_502_5@

完整代码:@H_502_5@

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

在上面的代码中,我们首先更改recyclelerView的viewType,然后我们在RecyclerView UI Handler Queue上更改GridLayoutManager的spanCount,以便顺序实现两个UI操作.@H_502_5@

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...