动画删除 ListView 项
Posted
技术标签:
【中文标题】动画删除 ListView 项【英文标题】:Animate the removal of a ListView item 【发布时间】:2012-09-17 17:13:39 【问题描述】:我正在尝试使用此:
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();
);
它不起作用。我基本上遵循了这篇文章顶部第四个答案的建议:
How to Animate Addition or Removal of android ListView Rows
但是,有一些有趣的绘图内容正在进行,或者回收,或者因为当动画发生时,滑出屏幕的项目下方的项目也因某种原因被删除。不幸的是,提问者最终标记为正确的答案是针对整个 Android 源的 RTFM。我已经查看了那里,但在 JellyBean 中找不到我试图模拟的通知下拉菜单。
TIA。 约翰
【问题讨论】:
接受@Alexey 的回答,这解释了为什么滑出屏幕的项目下方的项目也会被删除。您应该在动画完成后删除该项目,而不是在您开始动画的那一刻。 看看谷歌[解决方案][1]。这里只是一种删除方法。 [1]:***.com/questions/3928193/… 【参考方案1】:想法:当用户选择行时我开始动画。动画完成后,我从适配器中删除该行。以下代码为所选行设置动画:
@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 文件:
<?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>
【讨论】:
这会将ListView
项目滑到另一个ListView
项目之上,看起来很奇怪。但是如果您将android:fromYDelta="0%"
更改为android:fromXDelta="0%"
并将android:toYDelta="100%"
更改为android:toXDelta="-100%"
,则ListView
项目将从屏幕左侧滑出【参考方案2】:
我刚刚找到了一个漂亮的解决方案:https://github.com/paraches/ListViewCellDeleteAnimation
这里是视频:http://www.youtube.com/watch?v=bOl5MIti7n0
非常感谢'paraches' ;)
编辑
从 Android 版本 22.0.0 开始,新的 android.support.v7.widget.RecyclerView
可作为 ListView
的后续版本。标准的添加/删除/更新动画开箱即用。小部件动画也很容易自定义 (few custom animations)。
如果您需要自定义项目动画,我强烈建议您从 ListView
切换到 RecyclerView
。
【讨论】:
很好的例子,但我可以有类似的东西,但有添加功能吗? 这个java source code对我帮助很大。【参考方案3】:正如 Chet Haase 在 DevBytes 中指出的那样,https://www.youtube.com/watch?v=8MIfSxgsHIs,所有这些都将起作用,但不要忘记添加瞬态状态标志。
来自他的代码:
// 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();
【讨论】:
为什么我们必须使用 view.setAlpha(1);我注意到没有这个动画后视图不会被删除。 可能是因为瞬态,但我不确定。实际上,我们现在应该将 RecyclerViews 用于此类解决方案,它对开箱即用的动画有更好的支持。【参考方案4】:我在刷新 ListView 时使用了从上到下的幻灯片动画。这是我使用的代码:
adapter.notifyDataSetChanged();
Animation animation = AnimationUtils.loadAnimation(
getApplication(), R.anim.slide_top_to_bottom);
getListView().startAnimation(animation);
getListView().setSelection(0);
和slide_top_to_bottom.xml(保存在res/anim
文件夹中)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromYDelta="-100%" android:toXDelta="0" android:duration="100" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="50" />
</set>
编辑: 试试这个:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, final View view, final int i, long l)
ValueAnimator fader = ObjectAnimator.ofFloat(view, "alpha", 1, 0);
AnimatorSet animation = new AnimatorSet();
animation.addListener(new AnimatorListener()
@Override
public void onAnimationStart(Animator animation)
@Override
public void onAnimationRepeat(Animator animation)
@Override
public void onAnimationEnd(Animator animation)
@Override
public void onAnimationCancel(Animator animation)
);
((AnimatorSet) animation).play(fader);
animation.setDuration(500);
animation.start();
adapter.remove(tasks.get(i));
adapter.notifyDataSetChanged();
);
【讨论】:
以上是关于动画删除 ListView 项的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 动画列表:有条件地添加 ListView 项