android view.scrollBy 干扰拖动侦听器事件

如何解决android view.scrollBy 干扰拖动侦听器事件

我正在尝试使用 DragShadowBuilder

实现滚动

但是当我的 scrollBy 拖动事件调用 LOCATION 时,所有其他拖动事件都会延迟到视图滚动后的一段时间

特别是它们在滚动开始后延迟 1 秒到 4 秒

如果我不调用 scrollBy 那么我的事件会立即收到但我的视图不会滚动

我尝试使用 scrollBy 调用 ViewCompat.postOnAnimation 但这没有任何区别

我也尝试从单独的线程调用它,但这没有任何区别

虽然我必须使用 smoothScrollBy,因为 scrollBy 会抛出 not UI thread 异常

有谁知道我如何在滚动时解决这种响应滞后的问题?

因为我的要求是

  1. 我的视图必须可以拖动到 RecyclerView 之外的其他视图(并且能够与这些视图交互)

  2. 我的视图必须能够在被拖动时滚动回收器视图,使其位置位于回收器视图的底部或顶部

这是我当前的代码

// based on androidx.recyclerview.widget.itemtouchhelper source code

int startedX;
int startedY;
ViewHolder mSelected;
Shadowitemtouchhelper itemtouchhelper;
private Rect mTmpRect;
private long mDragScrollStartTimeInMs;
RecyclerView mRecyclerView;
Callback mCallback;
float x;
float y;

final Runnable mScrollRunnable = new Runnable() {
    @Override
    public void run() {
        if (mSelected != null && scrollIfNecessary()) {
            mRecyclerView.removeCallbacks(mScrollRunnable);
            ViewCompat.postOnAnimation(mRecyclerView,this);
        }
    }
};

boolean scrollIfNecessary() {
    if (mSelected == null) {
        mDragScrollStartTimeInMs = Long.MIN_VALUE;
        return false;
    }
    final long Now = System.currentTimeMillis();
    RecyclerView.LayoutManager lm = mRecyclerView.getLayoutManager();
    if (mTmpRect == null) {
        mTmpRect = new Rect();
    }
    int scrollX = 0;
    int scrollY = 0;
    lm.calculateItemdecorationsForChild(mSelected.itemView,mTmpRect);
    if (lm.canScrollHorizontally()) {
        int width = mRecyclerView.getMeasuredWidth();
        if (width - x < 200) {
            scrollX = (int) (mSelected.itemView.getWidth() * 0.2);
        } else if (width - x > width - 200) {
            scrollX = (int) (-mSelected.itemView.getWidth() * 0.2);
        }
    }
    if (lm.canScrollVertically()) {
        int height = mRecyclerView.getMeasuredHeight();
        if (height - y < 200) {
            scrollY = (int) (mSelected.itemView.getHeight() * 0.2);
        } else if (height - y > height - 200) {
            scrollY = (int) (-mSelected.itemView.getHeight() * 0.2);
        }
    }
    if (scrollX != 0 || scrollY != 0) {
        if (mDragScrollStartTimeInMs == Long.MIN_VALUE) {
            mDragScrollStartTimeInMs = Now;
        }

        // SCROLL
        mRecyclerView.scrollBy(scrollX,scrollY);

        return true;
    }
    mDragScrollStartTimeInMs = Long.MIN_VALUE;
    return false;
}

@Override
public boolean onDrag(View v,DragEvent event) {
    //noinspection unchecked
    Pair<Shadowitemtouchhelper,ViewHolder> data = (Pair<Shadowitemtouchhelper,ViewHolder>) event.getLocalState();

    final int action = event.getAction();
    switch(action) {
        case DragEvent.ACTION_DRAG_STARTED:
            toastList.show(dragStartedKey);
            Log.d(TAG,"onDrag: STARTED");
            itemtouchhelper = data.first;
            mRecyclerView = itemtouchhelper.mRecyclerView;
            mCallback = itemtouchhelper.mCallback;
            mSelected = data.second;
            startedX = mSelected.itemView.getLeft();
            startedY = mSelected.itemView.getTop();
            return true;
        case DragEvent.ACTION_DRAG_ENTERED:
            toastList.show(dragenteredKey);
            Log.d(TAG,"onDrag: ENTERED");
            mSelected = data.second;
            return true;

        case DragEvent.ACTION_DROP:
            toastList.show(dragDropKey);
            Log.d(TAG,"onDrag: DROP");
            mSelected = null;
            return true;
        case DragEvent.ACTION_DRAG_ENDED:
            toastList.show(dragEndedKey);
            Log.d(TAG,"onDrag: ENDED");
            mSelected = null;
            return true;
        case DragEvent.ACTION_DRAG_EXITED:
            toastList.show(dragExitedKey);
            Log.d(TAG,"onDrag: EXITED");
            mSelected = null;
            return true;

        case DragEvent.ACTION_DRAG_LOCATION:
            x = event.getX();
            y = event.getY();
            mRecyclerView.removeCallbacks(mScrollRunnable);
            mScrollRunnable.run();
            mRecyclerView.invalidate();
            return true;
    }
    return false;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?