【问题标题】:Collapsing CardView Animation not working correctly折叠 CardView 动画无法正常工作
【发布时间】:2018-08-09 19:59:40
【问题描述】:

我想要做什么

我有一个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 而不是卡本身来延迟转换,但这也不起作用。

我怎样才能为我的布局实现这种行为?

【问题讨论】:

  • 您是否尝试过手动为文本视图的高度设置动画?
  • 我没有。由于delayedTransition是为之前的布局工作的,我觉得没必要,直到现在……

标签: android android-recyclerview kotlin android-animation android-transitions


【解决方案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
          }
          

          【讨论】:

            猜你喜欢
            • 2016-12-11
            • 1970-01-01
            • 2018-05-02
            • 2020-04-23
            • 1970-01-01
            • 1970-01-01
            • 2014-08-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多