I am trying to animate recyclerview divider decorations as the actual view animates.
override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
val childCount = parent.childCount
for (i in 0 until childCount - 1) {
val child = parent.getChildAt(i)
val childAdapterPosition = parent.getChildAdapterPosition(child)
.let { if (it == RecyclerView.NO_POSITION) return else it }
val type = parent.adapter?.getItemViewType(childAdapterPosition)
val drawable = itemViewTypesMap(type)?.drawable ?: continue
val margin = itemViewTypesMap(type)?.margin?.toInt() ?: 0
val params = child.layoutParams as RecyclerView.LayoutParams
val childLeftOffset = child.paddingLeft + params.leftMargin
val childRightOffset = child.paddingRight + params.rightMargin
val dividerLeft = if (parent.clipToPadding) 0 + childLeftOffset else parent.paddingLeft + childLeftOffset
val dividerRight = if (parent.clipToPadding) parent.width - childRightOffset else parent.width - parent.paddingRight - childRightOffset
val dividerTop = child.bottom + params.bottomMargin + child.translationY.roundToInt()
val offset = child.animationMatrix?.values()?.get(5)?.toInt() ?: 0
val dividerBottom = dividerTop + drawable.intrinsicHeight
drawable.setBounds(dividerLeft + margin, dividerTop + offset, dividerRight - margin, dividerBottom + offset)
drawable.draw(canvas)
}
}
The code above is working great, but IDE complains about child.animationMatrix
that is added in api 29. Using child.matrix
does not work since it contains only 0.0 values. Also using child.getTranslationY always returns 0.0.
It should help that we use this kind of animations:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="@android:anim/decelerate_interpolator">
<translate
android:duration="400"
android:fromXDelta="0%"
android:fromYDelta="100%"
android:toXDelta="0%"
android:toYDelta="0%" />
</set>
and loading them by:
viewHolder.itemView.startAnimation(AnimationUtils.loadAnimation(viewHolder.itemView.context, R.anim.down_from_top))