我将RecyclerView
与GridLayoutManager
一起使用。用户可以在2到4之间切换跨度计数,这将生成一个动画,该动画将每个单元格的内置转换动画运行到新位置。到目前为止,我一直在使用的代码是:
TransitionManager.beginDelayedTransition(moviesGridRecycler);
gridLayoutManager.setSpanCount(NEW_SPAN_COUNT);
adapter.notifyDataSetChanged();
这对我来说很好,但是现在我需要为每个跨度计数使用不同的布局。为此,我在RecyclerView
中有2种视图类型,由于移动到新的跨度计数时视图类型已更改,因此RecyclerView
无法看到它是“相同”的内容,并且默认不运行翻译动画。
如果启用布局过渡,则将获得视图输入动画,而不是视图位置更改动画。两个跨度计数的单元格视图的宽度和高度分别为match_parent
和wrap_content
。
作为替代方案,我尝试将新的视图类型全部放在一起,只使用一种视图类型。我有一个FrameLayout
,其中包含两个跨度计数的视图。在onBindViewHolder()
中,我只是切换子视图的可见性。这也不会产生动画。
我关注了this thread和this 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
}
}
答案 0 :(得分:0)
对于您的问题,我有解决方案,将您的切换功能更改为:
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操作。