问题:
(1)向列表视图中的行添加触摸侦听器,以便轻扫。
(2)滑动动画播放
(3)在后端删除行,
(4)动画播放没有任何闪烁或急动。通过“闪烁”我的意思是在动画结束后简要显示删除的行。
我怀疑动画监听器发生了一些时髦的事情,所以我最终做了以下事情(按照给定的顺序完成):
结果删除没有急动或闪烁的行但是现在因为额外的300毫秒等待而感觉迟钝。 (我也不确定这种延迟是否适用于所有设备。)
更新:我应该指出300毫秒的延迟是它的工作原理。这很奇怪,因为到那时动画被重置并且listview具有最新数据。应该没有理由让视图显示使旧行简要显示,对吧?
我也尝试使用ViewPropertyAnimator(根据Using animation on a ViewPager and setFillAfter)但由于某种原因,onAnimationEnd侦听器在动画的每个步骤中被调用。
我还读到我们应该实现一个自定义视图并覆盖它的onAnimationEnd监听器。 (但是,我还没有尝试过这种方法。)
更新:刚尝试在最后添加一个额外的虚拟动画(根据Android Animation Flicker)。但是,这不起作用
我的测试手机运行Ice Cream Sandwich。我的应用程序的目标是姜饼和之后。
那么什么是正确的解决方案?我这样做是错误的吗?
以下是代码:
@Override
public boolean onTouch(final View view, MotionEvent event)
{
//...
switch(action) {
//...
case MotionEvent.ACTION_MOVE:
// ...
if (//check for fling
{
view.clearAnimation();
//animation = standard translate animation
animation.setAnimationListener(new AnimationListener() {
//
@Override
public void onAnimationEnd(Animation animation)
{
view.setVisibility(View.INVISIBLE);
flingListener.onFling(cursorPosition, view, velocity);
}
//...
});
view.startAnimation(animation);
}
break;
//
}
“狡猾的倾听者”:
@Override
public void onFling(int position, final View view, float velocity)
{
//delete row -- its actually a Loader
//the following code runs in the Loader's onLoadFinished
view.clearAnimation();
adapter.notifyDataSetChanged();
adapter.swapCursor(null);
//reload listview -- it's actually a Loader
//the following code runs in the Loader's onLoadFinished
adapter.swapCursor(cursor);
view.postDelayed(new Runnable() {
@Override
public void run()
{
view.setVisibility(View.VISIBLE);
}
}, 300);
}
更新:在比较Chet Haase的代码之后,我们做了类似的事情,但有一些重要的区别:(1)他使用onPreDraw监听器和ListView树观察器进行实际删除,(2)他不仅从数组中删除了行,还从listview中删除了该行。在模仿他的代码后,它仍然无法正常工作。现在的问题是Loader ---我使用Loader异步删除行。 Loader似乎强制对ListView进行额外的绘制调用... 之前在后端删除了行。这是闪烁的(另一个)原因。仍然没有想出一个解决方法。
答案 0 :(得分:2)
Chet Haase(谷歌工程师)在这个主题上汇集了一个非常好的DevBytes,我建议观察/从他的来源获取想法。如果您使用NineOldAndroids,我认为这将向后兼容GB。
在这里查看:
http://graphics-geek.blogspot.com/2013/06/devbytes-animating-listview-deletion.html
答案 1 :(得分:2)
正如我在评论中所指出的,Chet代码的问题在于其设计用于同步数据访问。一旦开始异步删除行,他的代码就会失败。
我通过将Chet的代码与这个答案结合起来找到了闪烁问题的解决方案:CursorAdapter backed ListView delete animation "flickers" on delete
以异步方式正确执行行删除的解决方案是:
一些使用AbstractCursor包装器的伪代码(技术上称为“代理”):
//Called when you swipe a row to delete
@Override
public void onFling(final int positionToRemove, final View view)
{
final ViewTreeObserver observer = listView.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
public boolean onPreDraw()
{
observer.removeOnPreDrawListener(this);
//remove the row from the matrix cursor
CursorProxy newCursor = new CursorProxy(cursor,
positionToRemove);
swapCursor(newCursor);
//delete row in database
}
}
}