RecyclerView的ItemTouchHelper在滑动时显示按钮
RecyclerView的ItemTouchHelper在滑动时显示按钮
我正在尝试将一些iOS功能移植到Android系统。
我打算创建一个表格,在向左滑动时显示两个按钮:编辑和删除。
我已经在研究这个问题,我知道我离成功很近了。关键在于OnChildDraw方法。
我想绘制一个适合于"删除"文本的矩形,然后在其旁边绘制"编辑"文本,它们各自具有相应的背景颜色。点击剩余的白色空间时,应将行恢复到初始位置。
我已经成功在用户向两侧滑动时绘制了背景,但我不知道如何添加监听器,一旦向一侧滑动,拖动功能就会出现问题。
我正在使用Xamarin进行开发,但纯Java的解决方案也可以接受,因为我可以很容易地将它们移植到C#。
这是我目前的代码。
如果您知道如何添加监听器或有任何建议,请留下评论!
更新:
我刚刚意识到,在行的剩余白色空间上双击已经可以将行恢复到初始状态了。不过,单击无效 🙁
RecyclerView ItemTouchHelper Buttons on Swipe
在RecyclerView中,有时我们需要在滑动操作中显示一些按钮,以便执行特定的操作。这可以通过使用ItemTouchHelper和自定义的SwipeHelper类来实现。
问题的原因:
- 当用户滑动RecyclerView中的项时,没有提供默认的按钮来执行特定的操作。
解决方法:
1. 创建一个SwipeHelper类,继承自ItemTouchHelper.SimpleCallback,用于处理滑动操作。
2. 在SwipeHelper类中实现onChildDraw方法,在滑动时绘制按钮。
3. 创建一个UnderlayButton类,用于表示每个按钮,并实现按钮的绘制和点击操作。
4. 在SwipeHelper类中实现instantiateUnderlayButton方法,根据位置返回相应的按钮列表。
5. 在使用RecyclerView的Activity或Fragment中,创建一个Adapter,并将其设置为RecyclerView的适配器。
6. 创建相应的按钮,并通过instantiateUnderlayButton方法返回按钮列表。
7. 使用ItemTouchHelper将SwipeHelper类附加到RecyclerView上。
使用示例:
private fun setUpRecyclerView() {
binding.recyclerView.adapter = Adapter(listOf(
"Item 0: No action",
"Item 1: Delete",
"Item 2: Delete & Mark as unread",
"Item 3: Delete, Mark as unread & Archive"
))
binding.recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
binding.recyclerView.layoutManager = LinearLayoutManager(this)
val itemTouchHelper = ItemTouchHelper(object : SwipeHelper(binding.recyclerView) {
override fun instantiateUnderlayButton(position: Int): List
var buttons = listOf
val deleteButton = deleteButton(position)
val markAsUnreadButton = markAsUnreadButton(position)
val archiveButton = archiveButton(position)
when (position) {
1 -> buttons = listOf(deleteButton)
2 -> buttons = listOf(deleteButton, markAsUnreadButton)
3 -> buttons = listOf(deleteButton, markAsUnreadButton, archiveButton)
else -> Unit
}
return buttons
}
})
itemTouchHelper.attachToRecyclerView(binding.recyclerView)
}
private fun deleteButton(position: Int): SwipeHelper.UnderlayButton {
return SwipeHelper.UnderlayButton(
this,
"Delete",
14.0f,
android.R.color.holo_red_light,
object : SwipeHelper.UnderlayButtonClickListener {
override fun onClick() {
toast("Deleted item $position")
}
}
)
}
// 创建其他按钮的方法类似
这种方法可以在滑动操作中显示自定义按钮,并在点击按钮时执行相应的操作。可以根据需要创建和配置不同的按钮,并在instantiateUnderlayButton方法中返回它们的列表。这种方法在2020年仍然是解决这个问题的最佳方法。
RecyclerView ItemTouchHelper Buttons on Swipe是一个在RecyclerView中实现滑动按钮效果的问题。这个问题的出现原因是大多数解决方案都使用了两层方法(一个是视图项,另一个是按钮),但是我想只使用ItemTouchHelper。最后,我想出了一个解决方案。原文代码中的SwipeHelper类实现了按钮的滑动效果。使用这个类可以实现在滑动RecyclerView项时显示按钮的效果。解决方法中的代码主要包括SwipeHelper类的实现以及用于使用SwipeHelper的示例代码。
解决方法中的SwipeHelper类是一个抽象类,继承自ItemTouchHelper.SimpleCallback。它通过重写ItemTouchHelper中的回调方法来实现滑动按钮的效果。在构造方法中,通过传递RecyclerView和Context参数来初始化SwipeHelper。在实现的方法中,我们可以自定义滑动的方向、按钮的样式和点击事件。在使用示例代码中,我们可以根据需要添加不同的UnderlayButton,并定义每个按钮的样式和点击事件。
在解决方法中,还提到了一些注意事项和已知的bug。例如,解决方法中提到的一个已知的bug是当我们将一个项斜向滑动到另一个项时,第一个被触摸的项会闪烁一下。解决这个bug的方法是减小getSwipeVelocityThreshold()方法的返回值。此外,根据需要,我们还可以调整getSwipeThreshold()和getSwipeEscapeVelocity()方法的返回值来调整滑动的感觉。
在解决方法的最后,还有这个解决方案的一些优化空间,并鼓励读者在使用过程中遇到问题时与作者联系。作者还附上了一个GIF图来展示这个解决方案的效果。
这个解决方法提供了一个简单而有效的实现,在RecyclerView中实现滑动按钮的效果。通过使用SwipeHelper类,我们可以轻松地实现滑动按钮,并根据需要自定义样式和点击事件。这个解决方案的优点是简单易用,同时也提供了一些优化和调整的空间,以满足不同的需求。
RecyclerView ItemTouchHelper在滑动时添加按钮的问题是因为原先的代码中只能绘制文本,无法绘制图像。为了解决这个问题,采取了以下方法:
1. 在SwipeHelper类中,将UnderlayButton构造方法的参数中的imageResId改为bitmap,并在构造方法中将传入的bitmap赋值给this.bitmap。
2. 在SwipeHelper的onDraw()方法中,使用drawBitmap()方法将bitmap绘制到画布上。
3. 在调用UnderlayButton的活动中,使用getBitmapFromVectorDrawable()方法将Drawable转换为Bitmap。
以下是完整的onDraw()方法代码,其中文本和图像都居中显示:
public void onDraw(Canvas c, RectF rect, int pos){ Paint p = new Paint(); // 绘制背景 p.setColor(color); c.drawRect(rect, p); // 绘制文本 p.setColor(Color.WHITE); p.setTextSize(24); float spaceHeight = 10; // 可根据需要调整 float textWidth = p.measureText(text); Rect bounds = new Rect(); p.getTextBounds(text, 0, text.length(), bounds); float combinedHeight = bitmap.getHeight() + spaceHeight + bounds.height(); c.drawBitmap(bitmap, rect.centerX() - (bitmap.getWidth() / 2), rect.centerY() - (combinedHeight / 2), null); // 如果需要同时绘制文本和图像 c.drawText(text, rect.centerX() - (textWidth / 2), rect.centerY() + (combinedHeight / 2), p); clickRegion = rect; this.pos = pos; }
如果想要使图像居中显示,可以尝试使用以下代码:
c.drawBitmap(bitmap, rect.left + x/2 - 1, rect.top + y/2 - 4, p);