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

时间:2016-03-03 13:22:43

标签: android canvas android-recyclerview swipe dismiss

我一直在努力解决这个问题,到目前为止,我还没有找到任何答案。

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

到目前为止一切顺利。

现在我有一个按钮可以刷一个项目,所以我试图手动调用ItemTouchHelper.onChildDraw(),这样我就可以重用我到目前为止所做的代码了。

问题是ItemTouchHelper.onChildDraw()需要Canvas作为参数,根据文档“RecyclerView正在绘制其子项的画布”。有没有办法从RecyclerView获得该画布?如果我执行ItemTouchHelper.onChildDraw(new Canvas()...)代码被执行但是在查看器后面没有任何东西被绘制,因为它显然不是recyclelerview正在使用的相同画布......也许有一种方法可以设置 recyclelerview使用的画布?

感谢正手的想法。

1 个答案:

答案 0 :(得分:1)

我解决这个问题的方法是创建一个自定义视图,扩展RecyclerView并保存android onDraw()生成的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是一个视图,需要在您想要滑动的ViewHolders的RecyclerView外部存在。我无法弄清楚如何在ViewHolder中滑动视图,所以我做的是刷一个位于屏幕上的视图(不可见),然后将过渡dX值传递给ItemtouchHelper.onChildDraw()