Reputation: 1139
I'm applying some AnimatorSet to the items of a recyclerView,
recyclerView adapter:
class MyAdapter(...) :
androidx.recyclerview.widget.RecyclerView.Adapter<MyAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, p1: Int): ViewHolder {
return ViewHolder(...)
}
override fun onBindViewHolder(p0: ViewHolder, p1: Int) {
p0.bind(...)
}
inner class ViewHolder(itemView: View,...) :
androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) {
fun bind(...) {
...
animateItemView(itemView)
...
}
}
}
animateItemView function
fun animateItemView(itemView: View) {
//hide the itemView
itemView.alpha = 0f
//moving the itemView down 400f
ObjectAnimator.ofFloat(itemView, "translationY", 0f, 400f)
.apply { duration = 1L }.start()
//show
//itemView.alpha = 1f
//moving the itemView up 400f
val translateUp = ObjectAnimator.ofFloat(itemView, "translationY", 400f, 0f)
.apply {
duration = 1000L
interpolator = AnticipateOvershootInterpolator(2f)
}
//animating alpha
val fade = ValueAnimator.ofFloat(0f, 1f)
.apply {
addUpdateListener {
itemView.alpha = this.animatedValue as Float
}
duration = 400L
}
//applying
AnimatorSet().apply { playTogether(translateUp, fade) }.start()
}
result:
surly when scrolling upwards the itemView
still slides up, is there a way to apply different animation for scrolling up/down ,, or what is a better approach ?
Upvotes: 0
Views: 3801
Reputation: 17258
I don't know why everyone is fascinated about putting everything into RecyclerView.Adapter
.
You can inject this animation into RecyclerView.LayoutManager
instead as it is aware of exact moment and position where views are added:
open class FadeInLinearLayoutManager : LinearLayoutManager {
constructor(context: Context?) : super(context)
constructor(context: Context?, orientation: Int, reverseLayout: Boolean) : super(context, orientation, reverseLayout)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
private val enterInterpolator = AnticipateOvershootInterpolator(2f)
override fun addView(child: View, index: Int) {
super.addView(child, index)
val h = 400f
// if index == 0 item is added on top if -1 it's on the bottom
child.translationY = if(index == 0) -h else h
// begin animation when view is laid out
child.alpha = 0.3f
child.animate().translationY(0f).alpha(1f)
.setInterpolator(enterInterpolator)
.setDuration(1000L)
}
}
Then use it as your layout manager:
recyclerView.layoutManager = FadeInLinearLayoutManager(context)
Upvotes: 3