I'm attempting to animate the removal of a ListView item using this:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, final View view, final int i, long l) {
view.animate().setDuration(500).x(-view.getWidth()).alpha(0f);
adapter.remove(tasks.get(i));
adapter.notifyDataSetChanged();
}
});
It does not work. I basically followed the advice of the 4th answer from the top of this post:
How to Animate Addition or Removal of Android ListView Rows
However, there's some funny drawing stuff going on, or recycling, or something because while the animation occurs, the item below the one that slides off screen also gets deleted for some reason. The answer that the question asker eventually marked as correct is unfortunately an RTFM towards the whole of Android's source. I've looked through there, and I can't find the notifications pull-down in JellyBean which I'm trying to emulate.
TIA. John
Idea: I start animation when the user selects the row. When the animation is complete i remove the row from the adapter.The following code animates the selected row:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listView = (ListView) findViewById(R.id.listView1);
final ArrayList<String> values = new ArrayList<String>();
values.add("Android");
values.add("iPhone");
values.add("WindowsMobile");
values.add("Blackberry");
values.add("Windows7");
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, values);
listView.setAdapter(adapter);
final Animation animation = AnimationUtils.loadAnimation(this,
R.anim.slide_out);
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
adapter.remove(adapter.getItem(selectedRow));
adapter.notifyDataSetChanged();
}
});
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
" " + values.get(position), Toast.LENGTH_LONG).show();
view.startAnimation(animation);
selectedRow = position;
}
});
}
slide_out.xml file:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:fromYDelta="0%"
android:toYDelta="100%"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
I just found a beautiful solution: https://github.com/paraches/ListViewCellDeleteAnimation
Here is video: http://www.youtube.com/watch?v=bOl5MIti7n0
Many thanks to 'paraches' ;)
Edit
As of Android version 22.0.0 the new android.support.v7.widget.RecyclerView
is available as a successor of ListView
. Standard add/remove/update animations are available out of the box. The widget animations are also easy to customize (few custom animations).
I strongly recommend switching from ListView
to RecyclerView
if you need custom item animations.
As Chet Haase points out in DevBytes, https://www.youtube.com/watch?v=8MIfSxgsHIs, all of this will work but don't forget to add transientState flags.
From his code:
// Here's where the problem starts - this animation will animate a View object.
// But that View may get recycled if it is animated out of the container,
// and the animation will continue to fade a view that now contains unrelated
// content.
ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, 0);
anim.setDuration(1000);
if (setTransientStateCB.isChecked()) {
// Here's the correct way to do this: if you tell a view that it has
// transientState, then ListView ill avoid recycling it until the
// transientState flag is reset.
// A different approach is to use ViewPropertyAnimator, which sets the
// transientState flag internally.
view.setHasTransientState(true);
}
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
cheeseList.remove(item);
adapter.notifyDataSetChanged();
view.setAlpha(1);
if (setTransientStateCB.isChecked()) {
view.setHasTransientState(false);
}
}
});
anim.start();
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