android - 在 RecyclerView 中展开 View 不能正确设置动画

标签 android xml animation android-recyclerview kotlin

我正在构建一个由 RecyclerView 内的多个 CardViews 组成的 UI。

<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.CardView
    android:id="@+id/card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardCornerRadius="5dp"
    app:cardElevation="1dp"
    app:cardBackgroundColor="#ddffca"
    android:animateLayoutChanges="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:padding="10dp"
    >
    <TextView
        android:id="@+id/tvHello"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="Hello there!"
        />

  <TextView
      android:id="@+id/test"
      android:layout_width="wrap_content"
      android:layout_height="50dp"
      android:visibility="gone"
      android:gravity="center"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@id/tvHello"
      android:text="GENERAL KENOBI!"
      />
</android.support.constraint.ConstraintLayout>
  </android.support.v7.widget.CardView>

我在里面指定了在点击时我的 test 文本会动画显示。它工作得很好,我对结果非常满意。但是只要我在 RecyclerView 中添加几张卡片,动画就会开始有点奇怪。我的意思是,考虑到其他 View 已经改变了它们的大小,未被触及的 View 没有正确地设置动画。相反,我看到另一个 View 在没有任何动画的情况下跳到它的新位置。 我怎样才能让它根据其他 View 进行动画处理?

编辑 我还提供了来自 onBindViewHolder 的代码。虽然它在 Kotlin 中:

override fun onBindViewHolder(
    holder: OperationsViewHolder,
    position: Int
  ) {

    var card: CardView = holder.cardView
    card.setOnClickListener {
      if (!operations.get(position).selected!!) {
        ObjectAnimator.ofFloat(card, "translationZ", 1f, 10f)
            .start()
        holder.test.visibility = View.VISIBLE;
        operations.get(position)
            .selected = true
      } else {
        ObjectAnimator.ofFloat(card, "translationZ", 10f, 1f)
            .start()
        holder.test.visibility = View.GONE;
        operations.get(position)
            .selected = false
      }

    }
  }

EDIT 2 我也试过将 android:animateLayoutChanges="true" 添加到所有元素,没有帮助

最佳答案

不确定这是否符合您问题的限制,但您不必手动设置展开/折叠动画。 RecyclerView 可以通过在您的适配器中正确使用 notifyItemChanged() 为您提供开箱即用的功能。

override fun onBindViewHolder(
    holder: OperationsViewHolder,
    position: Int
  ) {

    var card: CardView = holder.cardView

    if (operations.get(position).selected!!) {
        holder.test.visibility = View.VISIBLE;
    } else {
        holder.test.visibility = View.GONE;
    }

    card.setOnClickListener {
      if (!operations.get(position).selected!!) {
        operations.get(position)
            .selected = true
      } else {
        operations.get(position)
            .selected = false
      }
      notifyItemChanged(position)
    }
  }

上面的代码删除了动画逻辑,而是在每次单击 CardView 时调用 notifyItemChanged。这会告诉 RecyclerView 在该特定位置重新渲染项目,并免费为您提供重新渲染的动画。

关于android - 在 RecyclerView 中展开 View 不能正确设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51896557/

相关文章:

java - 如何在多个 Activity 中保持蓝牙连接?

android - Smali .local 格式

android - 按国家/地区 Android 绘制的绘图

java - 如何仅使用 Jackson 将 XML 转换为 JSON?

android - Activity启动后什么时候设置ViewPager的CurrentItem最好?

android - 在 android 2.x 上显示 SherlockDialogFragment

java - 如何将类名动态传递给 Testng XML 中的类标记

xml - 建议 xpath 检查相同类型的嵌套元素中的第一个 'text' 节点

java - 如何在两个不同点之间绘制移动动画线

android 在单击图像按钮时使用动画交换两个 View