CursorAdapter的支持ListView中删除动画和QUOT;闪烁"上删除 [英] CursorAdapter backed ListView delete animation "flickers" on delete
问题描述
我想实现刷卡删除,并在的ListView
使用 SwipeToDismissUndoList 图书馆延伸罗马Nurik的SwipeToDismiss 的样本。
我的问题是,在删除动画。因为的ListView
由后盾的CursorAdapter
,动画触发 onDismiss
回调 onAnimationEnd
但这意味着动画已经运行,并在的CursorAdapter
更新与删除自行复位
这最终看起来像一个闪烁的地方,他们通过刷卡它拿走删除笔记的用户,则认为是回来的一瞬间,然后消失,因为的CursorAdapter
回升的数据变化。
下面是我的 OnDismissCallback
:
私人SwipeDismissList.OnDismissCallback dismissCallback =
新SwipeDismissList.OnDismissCallback(){
@覆盖
公共SwipeDismissList.Undoable onDismiss(ListView控件的ListView,最终诠释位置){
光标C = mAdapter.getCursor();
c.moveToPosition(位置);
最终诠释ID = c.getInt(Query._ID);
最后一个项目的项目= Item.findById(getActivity(),身份证);
如果(Log.LOGV)Log.v(删除项目:+项目);
最后ContentResolver的CR = getActivity()getContentResolver()。
cr.delete(Items.buildItemUri(ID),NULL,NULL);
mAdapter.notifyDataSetChanged();
返回新SwipeDismissList.Undoable(){
公共无效撤消(){
如果(Log.LOGV)Log.v(恢复项目:+项目);
ContentValues CV =新ContentValues();
cv.put(Items._ID,item.getId());
cv.put(Items.ITEM_CONTENT,item.getContent());
cr.insert(Items.CONTENT_URI,CV);
}
};
}
};
我知道这个问题已经被标记为回答,但正如我在评论中,有使用MatrixCursor问题是,它的效率太低。复制所有行,除了要删除的行表示该行删除以线性时间运行(线性项目的数量在列表视图)。对于大型的数据和较慢的手机,这可能是不可接受的。
另一种方法是,以实现自己的AbstractCursor,忽略要删除的行。这将导致在绘制时,在一定的时间和可以忽略不计的性能损失假冒行删除运行。
一个简单的实现:
公共类CursorWithDelete扩展AbstractCursor {
私人光标指针;
私人诠释posToIgnore;
公共CursorWithDelete(光标指针,整数posToRemove)
{
this.cursor =光标;
this.posToIgnore = posToRemove;
}
@覆盖
公共布尔onMove(INT oldPosition,诠释在newPosition)
{
如果(在newPosition< posToIgnore)
{
cursor.moveToPosition(在newPosition);
}
其他
{
cursor.moveToPosition(在newPosition + 1);
}
返回true;
}
@覆盖
公众诠释getCount将()
{
返回cursor.getCount() - 1;
}
@覆盖
公众的String [] getColumnNames()
{
返回cursor.getColumnNames();
}
//等等。
//确保覆盖所有的方法AbstractCursor适当
请所有的步骤之前,除了:
- 在SwipeDismissList.OnDismissCallback.onDismiss(),创建新的CursorWithDelete。
- 交换了新的游标
I'm trying to implement swipe to delete and in a ListView
using the SwipeToDismissUndoList library which extends Roman Nurik's SwipeToDismiss sample.
My issue is in the delete animation. Since the ListView
is backed by a CursorAdapter
, the animation triggers the onDismiss
callback in onAnimationEnd
but this means that the animation has run and reset itself before the CursorAdapter
updates with the delete.
This ends up looking like a flicker to the user where they delete a note by swiping it away, then the view is back for a split second and then disappears because the CursorAdapter
has picked up the data change.
Here is my OnDismissCallback
:
private SwipeDismissList.OnDismissCallback dismissCallback =
new SwipeDismissList.OnDismissCallback() {
@Override
public SwipeDismissList.Undoable onDismiss(ListView listView, final int position) {
Cursor c = mAdapter.getCursor();
c.moveToPosition(position);
final int id = c.getInt(Query._ID);
final Item item = Item.findById(getActivity(), id);
if (Log.LOGV) Log.v("Deleting item: " + item);
final ContentResolver cr = getActivity().getContentResolver();
cr.delete(Items.buildItemUri(id), null, null);
mAdapter.notifyDataSetChanged();
return new SwipeDismissList.Undoable() {
public void undo() {
if (Log.LOGV) Log.v("Restoring Item: " + item);
ContentValues cv = new ContentValues();
cv.put(Items._ID, item.getId());
cv.put(Items.ITEM_CONTENT, item.getContent());
cr.insert(Items.CONTENT_URI, cv);
}
};
}
};
I know this question has been tagged as "answered" but as I pointed out in the comments, the problem with using a MatrixCursor is that it's too inefficient. Copying all the rows except for the row to be deleted means that row deletion runs in linear time (linear in the number of items in the listview). For large data and slower phones, that's probably unacceptable.
An alternate approach is to implement your own AbstractCursor that ignores the row to be deleted. This results in the fake row deletion running in constant time and with negligible performance penalty when drawing.
A sample implementation:
public class CursorWithDelete extends AbstractCursor {
private Cursor cursor;
private int posToIgnore;
public CursorWithDelete(Cursor cursor, int posToRemove)
{
this.cursor = cursor;
this.posToIgnore = posToRemove;
}
@Override
public boolean onMove(int oldPosition, int newPosition)
{
if (newPosition < posToIgnore)
{
cursor.moveToPosition(newPosition);
}
else
{
cursor.moveToPosition(newPosition+1);
}
return true;
}
@Override
public int getCount()
{
return cursor.getCount() - 1;
}
@Override
public String[] getColumnNames()
{
return cursor.getColumnNames();
}
//etc.
//make sure to override all methods in AbstractCursor appropriately
Follow all the steps as before except:
- In SwipeDismissList.OnDismissCallback.onDismiss(), create new CursorWithDelete.
- swap over the new cursor
这篇关于CursorAdapter的支持ListView中删除动画和QUOT;闪烁&QUOT;上删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!