OnTouchListener prevents visual feedback

I have a ListView that has an OnItemClickListener. In addition, each row (CardView) has an OnTouchListener for implementing validation gestures.

OnTouchListener responds to ACTION_DOWN, ACTION_CANCEL, ACTION_MOVE and ACTION_UP. I use performItemClick () when ACTION_UP occurs, so OnItemClickListener is called when required.

If I return my true value to OnTouchListener, the movement movement that I implemented through ACTION_MOVE works fine, clicking on an element also works. However, there is zero visual feedback. Typically, there will be ripple on Lollipop or a background change in ICS.

If I return False (this means that I do not want to intercept the event), then there is visual feedback and the click works ... But my OnTouchListener never intercepts any ACTION_MOVE event. This prevents any scrolling.

I tried various solutions, such as using v.setpressed (), but this had no effect.

I am curious to know how I could keep the ripple (or visual feedback in general) that would occur if my OnTouchListener did not intercept the event.

Here is my OnTouchListener, if you're interested.

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
    }
};

It is based on the Chet Haase demo a couple of years ago.

I really can't understand. Help?

Thank!

+4
source share
2 answers

, v.setPressed , v - , touch. , ACTION_DOWN v.setPressed(true) ACTION_UP v.setPressed(false)

+3

, , , . . ,

      columnViewHolder.rippleLayout.setOnClickListener((v) -> {

            dataManager.setProducts(id, response.getProducts());
            dataManager.setProductListPosition(id, position);
            dataManager.clearCurrentProductItem();
            Log.d(TAG, "product click " + product.toString());
            EventBus.getDefault().post(new ProductDetailEvent(id, product));
            tagManager.hubSpokeClick(product.getCode());

        });

, :

           columnViewHolder.rippleLayout.setOnClickListener((v) -> {

                handler.postDelayed(() -> {
                    dataManager.setProducts(id, response.getProducts());
                    dataManager.setProductListPosition(id, position);
                    dataManager.clearCurrentProductItem();
                    Log.d(TAG, "product click " + product.toString());
                    EventBus.getDefault().post(new ProductDetailEvent(id, product));
                    tagManager.hubSpokeClick(product.getCode());
                }, 200l);
         });
0

Source: https://habr.com/ru/post/1599732/


All Articles