CursorAdapter的支持ListView中删除动画和QUOT;闪烁"上删除 [英] CursorAdapter backed ListView delete animation "flickers" on delete

查看:183
本文介绍了CursorAdapter的支持ListView中删除动画和QUOT;闪烁"上删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现刷卡删除,并在的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆