当动画时折叠 RecyclerView 中的 CardView

22

我想做什么

我有一个默认情况下是隐藏的带有支持文本的CardView。当用户单击“操作箭头”时,我想让卡片的这个部分可见,如下图所示:

展开箭头

我知道可以通过将该View的可见性设置为VISIBLE来实现,但我还想对扩展和折叠事件进行动画处理。

问题及我迄今为止尝试过的内容

为此,我在我的CardView xml上使用了android:animateLayoutChanges="true"属性,当它正在展开时它正常工作。但是一旦我再次点击箭头来折叠支持文本,动画期间下面的卡片会重叠在我点击的卡片上。如何避免这种重叠?

编辑: 我知道可能可以像这个问题的解决方案那样做一些事情,但看起来过于复杂,因为存在android:animateLayoutChanges选项。我想知道是否可以使用该XML属性解决我的问题,保持简单。

我的动画代码如下:

Java代码

protected void expandCard() {
    if (isExpanded) {
        ibt_show_more.animate().rotation(0).start();
        isExpanded = false;
        tv_support.setVisibility(View.GONE);
    }
    else {
        ibt_show_more.animate().rotation(180).start();
        isExpanded = true;
        tv_support.setVisibility(View.VISIBLE);
    }
}

XML代码

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/spacing_small"
    card_view:cardCornerRadius="2dp"
    android:id="@+id/os_list_item_cv">

    <RelativeLayout
        android:id="@+id/os_list_item_rl_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true">

        <!-- Here goes the header, the image, the action buttons and so on -->
        <!-- Omitted on purpose -->
        <!-- ... -->

        <!-- This is the support TextView -->
        <TextView
            android:id="@+id/tv_support"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/os_list_item_rl_actions"
            android:text="@string/bacon_ipsum"
            android:paddingBottom="24dp"
            android:paddingEnd="16dp"
            android:paddingRight="16dp"
            android:paddingLeft="16dp"
            android:paddingStart="16dp"
            android:visibility="gone"/>

    </RelativeLayout>

</android.support.v7.widget.CardView>

完整性的GIF(具有错误的折叠行为)

在此输入图像描述


你可以使用自定义动画来替代android:animateLayoutChanges。例如,支持从0到1的缩放动画以展开视图,而从1到0的缩放动画则可用于折叠视图。 - Dharmendra
能否写一个示例作为答案? - Mauker
你可以发布你的动画代码吗? - Graeme
发布动画代码。 - Mauker
请添加您用于布局动画的XML。 - petey
如果将 RL 高度更改为 wrap_content,它是否有效? - petey
1个回答

28

在您更改可见性之前,请添加此行代码:

TransitionManager.beginDelayedTransition(the rootView containing the cardView, new AutoTransition()); 

你应该得到一个流畅的动画。在此之前,请从xml中删除“animateLayoutChanges=true”。

至于为什么这能起作用,调用TransitionManager.beginDelayedTransition()会使TransitionManger捕获父ViewGroup中当前的值,并在下一个动画帧中渲染动画。此处传递的Transition是一个AutoTransition,它负责处理父ViewGroup中所有的淡入淡出、移动和调整大小操作。

参见TransitionsTransitionManager

还要注意在适当的情况下使用来自支持库的Transitions,或执行必要的API级别检查。


2
感谢添加解释。请养成在您发布的所有答案中都这样做的习惯。 - Tim
我可以补充一下,如果我保持animateLayoutChanges=true"的话,当我把可见性设置为GONE时,只需要在此时才加入TransitionManager也是管用的。 - Mauker
请注意,提供给函数的 rootView 应该是所有应受动画影响的视图的父视图。 - William Reed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接