I have a problem when using an Animation in my Adapter.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(resource, parent, false);
holder = new ViewHolder();
holder.newRoomView = (TextView) convertView.findViewById(R.id.newRoom);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Room item = items.get(position);
// animate new rooms
if (item.isNewRoom()) {
AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f);
alphaAnim.setDuration(1500);
alphaAnim.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
holder.newRoomView.setVisibility(View.INVISIBLE);
}
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
});
holder.newRoomView.startAnimation(alphaAnim);
}
// ...
return convertView;
}
When adding a new room outside of the adapter and calling notifyDataSetChanged
the new room is correctly animated, but when onAnimationEnd
is called, another (not new room) is hidden.
Is there any way to get the correct room hidden?
Since you haven't declared the holder
variable in the getView()
method, I can only assume that you've declared it as an instance variable in your class. This is your problem. By the time the animation is completed, the variable holder
is holding a reference to a completely different item.
You need to use a local variable which is declared as final
inside the getView()
method. I don't know if you need this holder
variable outside the getView()
method or not, but if you do, you can do this:
// animate new rooms
if (item.isNewRoom()) {
final ViewHolder holderCopy = holder; // make a copy
AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f);
alphaAnim.setDuration(1500);
alphaAnim.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
holderCopy.newRoomView.setVisibility(View.INVISIBLE);
}
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
});
holder.newRoomView.startAnimation(alphaAnim);
}
This, of course, will not work if the animation takes so long that the view has been recycled in the meantime.
if (item.isNewRoom()) {
// store view reference first
final View newRoomView = holder.newRoomView;
...
alphaAnim.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
// hide exactly this view when animation ends
newRoomView.setVisibility(View.INVISIBLE);
}
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With