Material Design 是一种以平面化、简洁、明快、鲜明色彩和生动的动效为特点的设计语言,旨在提供更加统一的UI体验。在这个设计语言下,ListView 的滑动删除功能是一种常见的操作,本文将详细讲解如何在 Material Design 风格下实现该功能。
1. 实现思路
为了实现 ListView 的滑动删除功能,我们需要做如下工作:
- 在 ListView 中添加一个滑动删除的效果;
- 在滑动删除过程中,监听手势事件,根据手势的位移来移动删除按钮;
- 在删除按钮被点击后,从 ListView 中移除相应的数据项。
2. 实现步骤
2.1 添加滑动删除效果
在 Material Design 风格下,我们可以使用 ItemTouchHelper 来快速实现滑动删除的效果。ItemTouchHelper 是一个封装了滑动、拖拽等手势交互动作的类,通过与 RecyclerView 的配合使用,可以方便地实现滑动删除、拖拽重排等功能。
val itemTouchHelper = ItemTouchHelper(SwipeToDeleteCallback()) itemTouchHelper.attachToRecyclerView(recyclerView)
2.2 监听手势事件
在 SwipeToDeleteCallback 中,我们需要监听手指在界面上的滑动事件,以使得删除按钮跟随手指的滑动而移动。我们可以在 onChildDraw 方法中监听手势事件并根据手势的位移来移动删除按钮。
override fun onChildDraw( canvas: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) { super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { // 获取删除按钮的宽度 val deleteWidth = deleteBtn.intrinsicWidth // 计算删除按钮的左右坐标 val left = viewHolder.itemView.right - deleteMargin - deleteWidth val top = viewHolder.itemView.top + deleteMargin val right = viewHolder.itemView.right - deleteMargin val bottom = viewHolder.itemView.bottom - deleteMargin // 将删除按钮绘制到屏幕上 deleteBtn.setBounds(left, top, right, bottom) deleteBtn.draw(canvas) } }
2.3 根据手势的位移来移动删除按钮
在 onChildDraw 方法中,我们可以通过设置删除按钮的左右边距来实现删除按钮的移动效果。当手指左右滑动时,我们需要根据手指移动的距离来计算删除按钮的左右边距,并调用 invalidate 方法更新界面。
override fun onChildDraw( canvas: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) { super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { // 获取删除按钮的宽度 val deleteWidth = deleteBtn.intrinsicWidth // 计算删除按钮的左右坐标 val left = viewHolder.itemView.right - deleteMargin - deleteWidth val top = viewHolder.itemView.top + deleteMargin val right = viewHolder.itemView.right - deleteMargin val bottom = viewHolder.itemView.bottom - deleteMargin // 移动删除按钮 if (dX.abs() > deleteWidth) { deleteBtnBounds.left = (viewHolder.itemView.right - deleteMargin - deleteWidth).toInt() deleteBtnBounds.right = (viewHolder.itemView.right - deleteMargin).toInt() } else { deleteBtnBounds.left = (viewHolder.itemView.right - deleteMargin - deleteWidth + dX).toInt() deleteBtnBounds.right = (viewHolder.itemView.right - deleteMargin + dX).toInt() } deleteBtnBounds.top = top.toInt() deleteBtnBounds.bottom = bottom.toInt() deleteBtn.bounds = deleteBtnBounds deleteBtn.draw(canvas) // 刷新界面 viewHolder.itemView.invalidate() } }
2.4 从 ListView 中移除数据项
当用户点击删除按钮时,我们需要从 ListView 中移除相应的数据项。我们可以在 onSwiped 方法中处理删除事件,并调用 notifyItemRemoved 方法刷新界面。
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { val position = viewHolder.adapterPosition dataList.removeAt(position) adapter.notifyItemRemoved(position) }
3. 示例代码
下面是一个完整的示例代码,展示了如何在 Material Design 风格下实现 ListView 的滑动删除功能。
class MainActivity : AppCompatActivity() { private lateinit var recyclerView: RecyclerView private lateinit var adapter: MyAdapter private lateinit var dataList: MutableList<String> private lateinit var deleteBtn: Drawable private val deleteBtnBounds: Rect = Rect() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) recyclerView = findViewById(R.id.recycler_view) deleteBtn = resources.getDrawable(R.drawable.ic_delete, null) dataList = mutableListOf("Item 1", "Item 2", "Item 3", "Item 4", "Item 5") adapter = MyAdapter(dataList) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = adapter val itemTouchHelper = ItemTouchHelper(SwipeToDeleteCallback()) itemTouchHelper.attachToRecyclerView(recyclerView) } inner class MyAdapter(private val dataList: MutableList<String>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() { inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val textView: TextView init { textView = itemView.findViewById(R.id.text_view) } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_layout, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.textView.text = dataList[position] } override fun getItemCount(): Int { return dataList.size } } inner class SwipeToDeleteCallback : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) { private val deleteMargin = resources.getDimension(R.dimen.delete_margin) override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { return false } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { val position = viewHolder.adapterPosition dataList.removeAt(position) adapter.notifyItemRemoved(position) } override fun onChildDraw( canvas: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) { super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { // 获取删除按钮的宽度 val deleteWidth = deleteBtn.intrinsicWidth // 计算删除按钮的左右坐标 val left = viewHolder.itemView.right - deleteMargin - deleteWidth val top = viewHolder.itemView.top + deleteMargin val right = viewHolder.itemView.right - deleteMargin val bottom = viewHolder.itemView.bottom - deleteMargin // 移动删除按钮 if (dX.abs() > deleteWidth) { deleteBtnBounds.left = (viewHolder.itemView.right - deleteMargin - deleteWidth).toInt() deleteBtnBounds.right = (viewHolder.itemView.right - deleteMargin).toInt() } else { deleteBtnBounds.left = (viewHolder.itemView.right - deleteMargin - deleteWidth + dX).toInt() deleteBtnBounds.right = (viewHolder.itemView.right - deleteMargin + dX).toInt() } deleteBtnBounds.top = top.toInt() deleteBtnBounds.bottom = bottom.toInt() deleteBtn.bounds = deleteBtnBounds deleteBtn.draw(canvas) // 刷新界面 viewHolder.itemView.invalidate() } } } }
4. 总结
本文讲解了如何在 Material Design 风格下实现 ListView 的滑动删除功能。通过使用 ItemTouchHelper,我们可以快速地实现滑动删除的效果,并监听手势事件移动删除按钮,最终实现删除功能。相信读者通过阅读本文,已经掌握了如何实现 ListView 的滑动删除功能,并可以根据自己的需要进行修改和优化。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a90ecbadd4f0e0ff25c666