折叠 CardView 动画无法正常工作
Posted
技术标签:
【中文标题】折叠 CardView 动画无法正常工作【英文标题】:Collapsing CardView Animation not working correctly 【发布时间】:2018-08-09 19:59:40 【问题描述】:我想要做什么
我有一个RecyclerView
,其中有很多项目基本上都是CardView
。
这些卡片在它们的正文中间有一个支持文本,默认情况下它的可见性设置为GONE
,当我点击卡片右侧的箭头时,它变成了VISIBLE
。
我正在尝试在文本显示和折叠时为卡片设置动画。
下图显示了展开的卡片和折叠的卡片:
CardView
布局(为了便于阅读,我删除了一些部分):
<android.support.v7.widget.CardView
android:layout_
android:layout_
card_view:cardCornerRadius="3dp"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true"
android:id="@+id/root">
<LinearLayout
android:id="@+id/item_ll"
android:layout_
android:layout_
android:orientation="vertical"
android:padding="@dimen/activity_vertical_margin">
<!-- The header with the title and the item -->
<TextView
android:id="@+id/body_content"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_
android:layout_
android:padding="8dp"
android:layout_marginBottom="8dp"
android:text="@string/about_page_description"
android:textColor="@color/secondaryText"
android:visibility="gone"/>
<!-- The divider, and the footer with the timestamp -->
</LinearLayout>
</android.support.v7.widget.CardView>
问题
当卡片展开并显示身体 TextView
时,动画正在工作,但是,当我尝试将其折叠回来时,动画下方的卡片与第一个卡片重叠。
示例:
到目前为止我已经尝试过什么
我之前已经问过similar question about this behavior here,但该解决方案不适用于卡片中间的TextView
。
负责动画部分的代码位于RecyclerView
适配器内。箭头有一个点击监听器,它调用下面的方法:
private fun toggleVisibility()
if (bodyContent.visibility == View.GONE || bodyContent.visibility == View.INVISIBLE)
btSeeMore.animate().rotation(180f).start()
TransitionManager.beginDelayedTransition(root, AutoTransition())
bodyContent.visibility = View.VISIBLE
else
btSeeMore.animate().rotation(0f).start()
TransitionManager.beginDelayedTransition(root, AutoTransition())
bodyContent.visibility = View.GONE
root
是我的CardView
。
我也尝试使用 LinearLayout
而不是卡本身来延迟转换,但这也不起作用。
我怎样才能为我的布局实现这种行为?
【问题讨论】:
您是否尝试过手动为文本视图的高度设置动画? 我没有。由于delayedTransition是为之前的布局工作的,我觉得没必要,直到现在…… 【参考方案1】:您必须在 RecyclerView 上执行转换,而不是在单个项目上。否则,自动转换不会考虑 RecyclerView 布局更改,因为它只会查看该子视图中的哪些更改,即使实际上其他 ViewHolder 受到间接影响(布局参数正在更改)。
因此,不要将“根”(项目视图)传递给 TransitionManager#beginDelayedTransition,而是传递对 RecyclerView 的引用
【讨论】:
【参考方案2】:您必须在包含卡片视图的根视图上应用TransitionManager.beginDelayedTransition
您必须从整个布局中删除 android:animateLayoutChanges="true"
TransitionManager.beginDelayedTransition(the_root_view_where_card_view_exist, new AutoTransition());
【讨论】:
【参考方案3】:如果他的项目在 RecyclerViews 回调之外调整大小,RecyclerView 的行为确实很奇怪。尝试使用 adapter.notifyItemChanged(position, payload) 然后更新项目:
将适配器的 onclick 替换为:
adapter.notifyItemChanged(adapterPosition, true) // needs adapter reference, can use more meaningful payload
然后在您的适配器内部:
override fun onBindViewHolder(holder: Holder, position: Int, payloads: List<Any>)
if (payloads.isEmpty())
onBindViewHolder(holder, position)
else
holder.toggleVisibility()
您还可以看到在 LinearLayout 而不是 Card 本身上运行延迟转换时会发生什么。
这并不完美,但它会触发跟随项目的动画,而不是它们的跳跃和剪辑。
【讨论】:
【参考方案4】:我建议您使用 Animator 框架并将高度动画应用于您的 TextView。
这是一个不错的库,您可以使用:https://github.com/cachapa/ExpandableLayout
我也建议你检查它是source code,它使用了动画师
【讨论】:
【参考方案5】:也许为时已晚。 在 onBindViewHolder() 里面包含这个
holder.view.btSeeMore.setOnClickListener view ->
val seeMore = (bodyContent.visibility != View.VISIBLE)
view.animate().rotation(if (seeMore) 180f else 0f).start()
bodyContent.visibility = if (seeMore) View.VISIBLE else View.GONE
【讨论】:
以上是关于折叠 CardView 动画无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
如何在Android中加载带有动画的cardview GridView?
通过单击或滑动手势(Android)展开/折叠 CardView?
dev gridcontrol CardView 如何禁止折叠