我有一个RecyclerView
,其中有很多项基本上都是CardView
。
这些卡片在其正文中间有一个支持文字,默认情况下其可见性设置为GONE
,当我点击卡片右侧的箭头时,它会显示VISIBLE
。
我试图在文字显示时以及在文本崩溃时为卡片制作动画。
下图显示了扩展卡和折叠卡:
CardView
布局(为了便于阅读,我删除了一些部分):
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="3dp"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true"
android:id="@+id/root">
<LinearLayout
android:id="@+id/item_ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
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_width="match_parent"
android:layout_height="wrap_content"
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
代替卡本身进行延迟转换,但这也无效。
如何为布局实现这种行为?
答案 0 :(得分:2)
您必须在RecyclerView上执行转换,而不是在单个项目上执行转换。否则,自动转换不会考虑RecyclerView布局更改,因为它只会查看该子视图中的更改,即使事实上其他ViewHolders也会间接受到影响(布局参数也在发生变化)。
因此,不是将“root”(项目视图)传递给TransitionManager#beginDelayedTransition,而是将引用传递给RecyclerView
答案 1 :(得分:0)
我建议你使用Animator框架并将高度动画应用到TextView。
这是一个很好的库,你可以使用:https://github.com/cachapa/ExpandableLayout
我还建议您检查source code,它使用动画师
答案 2 :(得分:0)
如果他的物品在RecyclerViews回调之外调整大小,那么RecyclerView确实表现得很奇怪。尝试使用adapter.notifyItemChanged(位置,有效负载)并更新项目:
用以下方法替换适配器的on:
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本身上运行delayedTransition时会发生什么。
这不是完美的,但会触发以下项目的动画,而不是跳跃和剪辑。
答案 3 :(得分:0)
也许这太迟了。 在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
}
答案 4 :(得分:0)
您必须在包含Cardview的根视图上应用TransitionManager.beginDelayedTransition
您必须从整个布局中删除android:animateLayoutChanges="true"
TransitionManager.beginDelayedTransition(the_root_view_where_card_view_exist, new AutoTransition());