android - OnTouchListener 防止视觉反馈

标签 android android-listview expandablelistview ontouchlistener

我有一个 ListView,它有一个 OnItemClickListener。最重要的是,每一行 (CardView) 都有一个 OnTouchListener 以实现滑动手势。

OnTouchListener 对 ACTION_DOWN、ACTION_CANCEL、ACTION_MOVE 和 ACTION_UP 作出 react 。我在 ACTION_UP 发生时使用 performItemClick(),以便在需要时调用 OnItemClickListener。

如果我在 OnTouchListener 中返回 true,我通过 ACTION_MOVE 实现的滑动 Action 将完美运行,单击该项目也将正常运行。 但是,视觉反馈为零。通常,Lollipop 上会出现涟漪或 ICS 上会出现背景变化。

如果我返回 False(意味着我不想拦截该事件),则会有一个视觉反馈并且点击有效...但是我的 OnTouchListener 从不拦截任何 ACTION_MOVE 事件。这可以防止任何滑动。

我尝试了多种解决方案,例如使用 v.setpressed() 但没有效果。

我很想知道如果我的 OnTouchListener 没有拦截该事件,我如何才能保持波动(或一般的视觉反馈)。

如果你好奇的话,这是我的 OnTouchListener。

private final View.OnTouchListener mTouchListener = new View.OnTouchListener() {
    float mDownX;
    private int mSwipeSlop = -1;
    private boolean mItemPressed;
    private VelocityTracker mVelocityTracker = null;
    private HashMap<Long, Integer> mItemIdTopMap = new HashMap<>();

    @Override
    public boolean onTouch(final View v, MotionEvent event) {
        int index = event.getActionIndex();
        int pointerId = event.getPointerId(index);

        if (mSwipeSlop < 0) {
            mSwipeSlop = ViewConfiguration.get(getActivity())
                    .getScaledTouchSlop();
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (mItemPressed) {
                    // Multi-item swipes not handled
                    return false;
                }
                mItemPressed = true;
                mDownX = event.getX();
                if (mVelocityTracker == null) {
                    // Retrieve a new VelocityTracker object to watch the velocity of a motion.
                    mVelocityTracker = VelocityTracker.obtain();
                } else {
                    // Reset the velocity tracker back to its initial state.
                    mVelocityTracker.clear();
                }
                mVelocityTracker.addMovement(event);
                break;
            case MotionEvent.ACTION_CANCEL:
                v.setAlpha(1);
                v.setTranslationX(0);
                mItemPressed = false;
                mVelocityTracker.recycle();
                mVelocityTracker = null;
                break;
            case MotionEvent.ACTION_MOVE: {
                mVelocityTracker.addMovement(event);
                float x = event.getX() + v.getTranslationX();
                float deltaX = x - mDownX;
                float deltaXAbs = Math.abs(deltaX);
                if (!mSwiping) {
                    if (deltaXAbs > mSwipeSlop) {
                        mSwiping = true;
                        getListView().requestDisallowInterceptTouchEvent(true);
                        mBackgroundContainer.showBackground(v.getTop(), v.getHeight());
                    }
                }
                if (mSwiping) {
                    v.setTranslationX((x - mDownX));
                    v.setAlpha(1 - deltaXAbs / v.getWidth());
                }
            }
            break;
            case MotionEvent.ACTION_UP: {
                // User let go - figure out whether to animate the view out, or back into place
                if (mSwiping) {
                    float x = event.getX() + v.getTranslationX();
                    float deltaX = x - mDownX;
                    float deltaXAbs = Math.abs(deltaX);
                    float fractionCovered;
                    float endX;
                    float endAlpha;
                    final boolean remove;
                    mVelocityTracker.computeCurrentVelocity(1000);
                    float velocityX = Math.abs(VelocityTrackerCompat.getXVelocity(mVelocityTracker, pointerId));
                    if (velocityX > 700 || deltaXAbs > v.getWidth() / 4) {
                        // fixme
                        fractionCovered = deltaXAbs / v.getWidth();
                        endX = deltaX < 0 ? -v.getWidth() : v.getWidth();
                        endAlpha = 0;
                        remove = true;
                    } else {
                        // Not far enough - animate it back
                        fractionCovered = 1 - (deltaXAbs / v.getWidth());
                        endX = 0;
                        endAlpha = 1;
                        remove = false;
                    }
                    mVelocityTracker.clear();

                    int SWIPE_DURATION = 600;
                    long duration = (int) ((1 - fractionCovered) * SWIPE_DURATION);
                    getListView().setEnabled(false);
                    v.animate().setDuration(duration).
                            alpha(endAlpha).translationX(endX).
                            withEndAction(new Runnable() { // fixme replace with AnimationListener
                                @Override
                                public void run() {
                                    // Restore animated values
                                    v.setAlpha(1);
                                    v.setTranslationX(0);
                                    if (remove) {
                                        animateRemoval(getListView(), v);
                                    } else {
                                        mBackgroundContainer.hideBackground();
                                        mSwiping = false;
                                        getListView().setEnabled(true);
                                    }
                                }
                            });
                } else {
                    int position = getListView().getPositionForView(v);
                    if (position != ListView.INVALID_POSITION)
                        getListView().performItemClick(v, position, getListView().getItemIdAtPosition(position));
                }
            }
            mItemPressed = false;
            break;
            default:
                return false;
        }
        return true;
    }

    private void animateRemoval(final ListView listview, View viewToRemove) {
        // irrelevant
    }
};

它基于 Chet Haase 的 demo从几年前开始。

我实在想不通。帮忙?

谢谢!

最佳答案

对我来说,v.setPressed 起到了作用,其中 v 是接收触摸事件的 View 。这意味着我在 ACTION_DOWN 上调用了 v.setPressed(true),在 ACTION_UP 上调用了 v.setPressed(false)

关于android - OnTouchListener 防止视觉反馈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31638223/

相关文章:

android - 如何防止用户关闭GPS、Wifi和蓝牙?

java - 从 Android 应用程序连接到 MySQL 服务器

android - 无法将标题 View 添加到列表 - setAdapter 已被调用

android - ExpandableListView 指示器图标取决于组状态

ios - 如何制作一个可扩展的 tableview 来显示 iOS 的其余细节?

当我点击组时,Android Expandable ListView 会自动滚动到底部

java - 使用runOnUiThread更新Listview

java - 自定义对话框 onClickListener

java - android.widget.RelativeLayout android 不正确调用 requestLayout()

android - 从点击的 ListView 开始新 Activity 的最佳方式