手动调用 ItemTouchHelper.onChildDraw() 以在 RecyclerView 上滑动项目

Call ItemTouchHelper.onChildDraw() manually to swipe item on RecyclerView

我已经为此苦苦挣扎了一段时间,到目前为止我还没有找到任何答案。

我有一个带有 ItemTouchHelper 的 recyclerview 来检测滑动操作。当我在 recyclerview 中滑动一个项目时,我正在使用 ItemTouchHelper.onChildDraw() 在正在滑动的 viewholder 后面绘制一些东西。

到目前为止一切顺利。

现在我有一个应该滑动项目的按钮,所以我尝试手动调用 ItemTouchHelper.onChildDraw() 这样我就可以重用到目前为止完成的代码。

问题是 ItemTouchHelper.onChildDraw()Canvas 作为参数,根据文档,它是 "The canvas which RecyclerView is drawing its children"。有没有办法从 RecyclerView 中获取 canvas?如果我这样做 ItemTouchHelper.onChildDraw(new Canvas()...) 代码会被执行,但在 viewholder 后面没有绘制任何东西,因为它显然与 recyclerview 使用的 canvas 不一样......也许有办法 set a canvas 被recyclerview使用?

感谢正手的指点。

我解决这个问题的方法是创建一个扩展 RecyclerView 的自定义视图并保存由 android onDraw() 生成的 canvas 对象。然后,每当我想通过代码手动触发滑动时,我都可以获取相同的 canvas。

public class CanvasRecyclerView extends RecyclerView {
    private Canvas mCanvas;

    public CanvasRecyclerView(final Context context) { super(context); }

    public CanvasRecyclerView(final Context context, @Nullable final AttributeSet attrs) { super(context, attrs); }

    @Override public void onDraw(final Canvas c) {
        mCanvas = c;
        super.onDraw(c);
    }

    public Canvas getCanvas() {
        return mCanvas;
    }
}

希望对您有所帮助!

更新

要手动滑动 RecyclerView 项目,可以这样做(警告,非常 hackish):

private fun swipeCard(direction: Int) {
    val visibleChild = (recyclerView?.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
    val holder = recyclerView?.findViewHolderForAdapterPosition(visibleChild) ?: return

    val dX = if (direction == LEFT) -holder.itemView.width else holder.itemView.width

    val translation = SwipeAnimation(dX.toFloat()) //your translation here
    translation.setSwipingElements(recyclerView, touchHelper, holder)
    emptyView.startAnimation(translation)
}

emptyView 是一个 View,需要存在于 RecyclerView 之外,并带有您要滑动的 ViewHolder。我不知道如何滑动 ViewHolder 中膨胀的视图,所以我所做的是滑动位于屏幕上的视图(不可见),然后将过渡 dX 值传递给 ItemtouchHelper.onChildDraw().