我正在尝试实施滑动以删除与Gmail应用相同的内容"滑动以存档":
我尝试了很多教程,但没有一个像gmail一样快, 我更喜欢不在外部库上工作。我该怎么办?
编辑:
到目前为止我的代码 -
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// final int fromPos = viewHolder.getAdapterPosition();
// final int toPos = viewHolder.getAdapterPosition();
// // move item in `fromPos` to `toPos` in adapter.
return true;// true if moved, false otherwise
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
//Remove swiped item from list and notify the RecyclerView
mAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
我设法启用了滑动手势,但我不知道如何在viewHolder 下添加背景和图片。我试图将另一个FrameLayout放在item_XXX.xml文件中,但是在滑动时它会抛出整个项目的背景。
答案 0 :(得分:25)
RecyclerView Swipe的简单代码:
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.DOWN | ItemTouchHelper.UP) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
Toast.makeText(ListActivity.this, "on Move", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
Toast.makeText(ListActivity.this, "on Swiped ", Toast.LENGTH_SHORT).show();
//Remove swiped item from list and notify the RecyclerView
int position = viewHolder.getAdapterPosition();
arrayList.remove(position);
adapter.notifyDataSetChanged();
}
};
然后使用以下语句为recyclelerView设置回调:
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(rv);
答案 1 :(得分:24)
前几天我不得不这样做,我遇到了一些问题所以我决定写一篇博文。不需要第三方库。
基本上,您不会通过onChildDraw
绘制“撤消状态”,而是通过ViewHolder
完成。另外,您实际上不会删除onSwipe
中的行,只需将其标记为“待删除”,并通知适配器以“撤消状态”重新绑定它。同时你发布Runnable
实际上在x秒内删除行除非按下撤销按钮...
答案 2 :(得分:1)
SwipeableRecyclerView rv = findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(mAdapter);
rv.setListener(new SwipeLeftRightCallback.Listener() {
@Override
public void onSwipedLeft(int position) {
mList.remove(position);
mAdapter.notifyDataSetChanged();
}
@Override
public void onSwipedRight(int position) {
mList.remove(position);
mAdapter.notifyDataSetChanged();
}
});
两侧滑动的xml
<com.tsuryo.swipeablerv.SwipeableRecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:leftBgColor="@color/colorAccent"
app:leftImage="@drawable/ic_remove"
app:leftText="Delete"
app:rightBgColor="@color/blue"
app:rightImage="@drawable/ic_check"
app:rightText="Read"
app:textColor="@android:color/white"
app:textSize="20sp" />
答案 3 :(得分:1)
这是您的onCreate
中设置“向左轻扫以删除”的最小代码:
binding.rows.adapter = adapter
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
override fun onMove(v: RecyclerView, h: RecyclerView.ViewHolder, t: RecyclerView.ViewHolder) = false
override fun onSwiped(h: RecyclerView.ViewHolder, dir: Int) = adapter.removeAt(h.adapterPosition)
}).attachToRecyclerView(binding.rows)
这假设您的Adapter
类具有removeAt
函数。我的看起来像这样:
fun removeAt(index: Int) {
items.removeAt(index) // items is a MutableList
notifyItemRemoved(index)
}
感谢@RahulRaina您的Java回答!
答案 4 :(得分:-1)
完全基于@RahulRaina答案
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder,
@NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
((ItemsAdapter.ViewHolder) viewHolder).remove();
}
}).attachToRecyclerView(binding.recyclerView);
在我的适配器命名为ItemsAdapter
的情况下,其视图持有者是其子类,并在其中命名为ViewHolder
,并且remove
方法除持久保存数据外,还应调用notifyDataSetChanged()
。
答案 5 :(得分:-2)
这肯定会奏效。如果你想要小吃店,那么在你的xml中使用coordinatorLayout。您可以像gmail一样设置背景。如果您有任何想法,只需点击链接
即可https://drive.google.com/open?id=11ZOrjMMSjdskt8gG8RP52V5Al5yE50dD
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)
{
Drawable background;
Drawable xMark;
int xMarkMargin;
boolean initiated;
private void init() {
background = new ColorDrawable(Color.RED);
xMark = ContextCompat.getDrawable(Activity.this, R.drawable.ic_delete_svg);
xMark.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
initiated = true;
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
Toast.makeText(Activity.this, "on Move", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
/*Toast.makeText(mcontext, "on Swiped ", Toast.LENGTH_SHORT).show();*/
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "Deleted Successfully", Snackbar.LENGTH_LONG)
.setAction("UNDO", new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar snackbar1 = Snackbar.make(coordinatorLayout, "Message is restored!", Snackbar.LENGTH_SHORT);
snackbar1.show();
}
});
snackbar.show();
//Remove swiped item from list and notify the RecyclerView
int position = viewHolder.getAdapterPosition();
arrayList.remove(position);
adapter.notifyDataSetChanged();
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
View itemView = viewHolder.itemView;
// not sure why, but this method get's called for viewholder that are already swiped away
if (viewHolder.getAdapterPosition() == -1) {
// not interested in those
return;
}
if (!initiated) {
init();
}
// draw red background
background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
background.draw(c);
int xMarkLeft = 0;
int xMarkRight = 0;
int xMarkTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2;
int xMarkBottom = xMarkTop + intrinsicHeight;
if (dX < 0) {
xMarkLeft = itemView.getRight() - xMarkMargin - intrinsicWidth;
xMarkRight = itemView.getRight() - xMarkMargin;
} else {
xMarkLeft = itemView.getLeft() + xMarkMargin;
xMarkRight = itemView.getLeft() + xMarkMargin + intrinsicWidth;
}
xMark.setBounds(xMarkLeft, xMarkTop, xMarkRight, xMarkBottom);
xMark.draw(c);
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);