我在RecyclerView中有一个简单项目列表 . 使用ItemTouchHelper实现“轻扫到删除”行为非常容易 .
public class TripsAdapter extends RecyclerView.Adapter<TripsAdapter.VerticalItemHolder> {
private List<Trip> mTrips;
private Context mContext;
private RecyclerView mRecyclerView;
[...]
//Let adapter know his RecyclerView. Attaching ItemTouchHelper
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new TripItemTouchHelperCallback());
itemTouchHelper.attachToRecyclerView(recyclerView);
mRecyclerView = recyclerView;
}
[...]
public class TripItemTouchHelperCallback extends ItemTouchHelper.SimpleCallback {
public TripItemTouchHelperCallback (){
super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.RIGHT);
}
@Override
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//some "move" implementation
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
//AND WHAT HERE?
}
}
}
它运作良好 . 但是我还需要实现一些撤消操作或确认 . 做这个的最好方式是什么?
第一个问题是如何使用确认对话框插入另一个视图代替删除?如果用户选择撤消删除,如何恢复刷卡项目?
4 回答
我同意@Gabor最好软删除项目并显示撤消按钮 .
但是我正在使用Snackbar来展示UNDO . 这对我来说更容易实现 .
我正在将Adapter和RecyclerView实例传递给我的ItemTouchHelper回调 . 我的onSwiped很简单,大部分工作都是通过适配器完成的 .
这是我的代码( edited 2016/01/10 ):
适配器的onItemRemove方法是:
photosToDelete是myAdapter的ArrayList字段 . 我在recyclelerView主机片段的onPause()方法中真正删除了这些项目 .
注 edit 2016/01/10 :
改变了硬编码的位置,正如@Sourabh在评论中所建议的那样
有关RV的适配器和片段的完整示例,请参阅this gist
通常的方法是不要在刷卡时立即删除该项目 . 提出一条消息(它可能是一个小吃吧,或者像在Gmail中一样,覆盖刚刚刷过的项目的消息),并为消息提供超时和撤消按钮 .
如果用户在消息可见时按下撤消按钮,您只需关闭该消息并返回正常处理 . 仅在超时超过而没有用户按下撤销按钮的情况下删除实际项目 .
基本上,这些方面的东西:
这假设项目视图中存在
undo
布局,通常是不可见的,包含两个项目,一个文本(说明已删除或类似)和一个撤消按钮 .点击按钮只会删除消息 . (可选)点击文本确认删除并通过调用代码中的相应回调立即删除项目 . 唐't forget to call back to your adapter' s
notifyItemRemoved()
:我试过JirkaV's solution,但它正在抛出
IndexOutOfBoundsException
. 我能够修改他的解决方案,为我工作 . 如果您遇到问题,请尝试并告诉我 .它是如何工作的
当用户滑动时,会显示一个快餐栏,并从数据集中删除该项目,因此:
由于填充recyclerView时使用的数据来自SQL数据库,因此此时不会从数据库中删除滑动的项目 .
当用户点击“UNDO”按钮时,只需将刷过的物品带回,并将recyclerView滚动到刚刚重新添加的项目的位置 . 因此:
然后当小吃店解散时,我检查用户点击“UNDO”按钮是否解除了小吃吧 . 如果不是,我此时从数据库中删除该项 .
可能这个解决方案存在性能问题,我还没有发现任何问题 . 如果您发现任何问题,请删除您的评论 .
我已经找到了更简单的方法来执行删除确认对话框:
注意:
删除委托给ViewModel,成功时更新mRecyclerViewAdapter .
为项目"return"你只需要调用mRecyclerViewAdapter.notifyItemChanged
cancelListener和negativeButtonListener执行相同的操作 . 如果您不希望用户在对话框外点击,则可以选择使用.setCanclable(false)