Android - Разрешить пролистывание, распространить щелчок - PullRequest
0 голосов
/ 06 мая 2020

Я все,

мое приложение состоит из:

  • общего c действия

  • много фрагментов с разными шаблонами.

диаграмма

Каждый фрагмент загружается в контейнер активности.

Это действие имеет вид (оверлей), который занимает 20% экрана.

Я бы хотел, чтобы оверлей допускал вертикальное смахивание и распространял любые щелчки на нижележащие фрагменты.

Смахивание позволяет для изменения размера контейнера фрагмента.

На данный момент я могу провести пальцем, но щелчок не управляется правильно.

Чтобы щелкнуть, например, заднюю часть фрагмента «A» на рисунке, Мне нужно щелкнуть дважды.

Я уверен, что моя ошибка связана с плохим управлением

dispatchTouchEvent

, но я не могу понять

Это код активность

public class GenericActivity extends AppCompatActivity  {

    float oldX, oldY;
    float maxScale = 1.0f;
    float minScale = 0.85f;
    float stepScale = 0.01f;
    float scale = maxScale;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // ... binding and inflating stuff

    mBinding.dragView.setOverLayerTouchDownListener(new GestureButtonLayout.OnOverLayerTouchDownListener() {
        @Override
        public void onOverLayerTouchDown(MotionEvent motionEvent) {
            oldX = motionEvent.getX();
            oldY = motionEvent.getY();
        }
    });

    mBinding.dragView.setOverLayerTouchMoveListener(new GestureButtonLayout.OnOverLayerTouchMoveListener() {
        @Override
        public void onOverLayerTouchMove(float x, float y) {

            int newX = (int) x;
            int newY = (int) y;

            float deltaX = oldX - newX;
            float deltaY = oldY - newY;

            if (Math.abs(deltaY) > Math.abs(deltaX)) {
                // Motion in Y direction.

                if (deltaY < 0) {
                    // up
                    if (scale > minScale) {
                        scale -= stepScale;
                    }
                } else {
                    // down
                    if (scale < maxScale) {
                        scale += stepScale;
                    }
                }

                mBinding.host.setScaleX(scale);
                mBinding.host.setScaleY(scale);

            } else {
                // Motion in X direction.
            }
        }
    });

    mBinding.dragView.setOverLayerTouchUpListener(new GestureButtonLayout.OnOverLayerTouchUpListener() {
        @Override
        public void onOverLayerTouchUp(MotionEvent motionEvent) {

            if (scale <= minScale) {
                mBinding.host.setScaleX(minScale);
                mBinding.host.setScaleY(minScale);
                // close the activity
                finish();
            } else {
                mBinding.host.setScaleX(maxScale);
                mBinding.host.setScaleY(maxScale);
            }
        }
    });
}
}

, а это код для наложения

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;

public class GestureButtonLayout extends FrameLayout {

private OnOverLayerTouchDownListener mTouchDownListener;
private OnOverLayerTouchUpListener mTouchUpListener;
private OnOverLayerTouchMoveListener mTouchMoveListener;

private final float CLICK_THRESHOLD = 200;
private long startClick;

public GestureButtonLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public GestureButtonLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public GestureButtonLayout(Context context) {
    super(context);
}

public void setOverLayerTouchDownListener(OnOverLayerTouchDownListener l) {
    mTouchDownListener = l;
}

public void setOverLayerTouchUpListener(OnOverLayerTouchUpListener l) {
    mTouchUpListener = l;
}

public void setOverLayerTouchMoveListener(OnOverLayerTouchMoveListener l) {
    mTouchMoveListener = l;
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (isEnabled()) {
        processEvent(event);

        super.dispatchTouchEvent(event);

        return true;
    }
    return super.dispatchTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return false;
}

private boolean processEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            startClick = System.nanoTime();
            touchDown(event);
            break;
        case MotionEvent.ACTION_MOVE:
            touchMove(event);
            break;
        case MotionEvent.ACTION_UP:
            if ((System.nanoTime() - startClick) / 1e6 <= CLICK_THRESHOLD) {
                setEnabled(false);
            } else {
                touchUp(event);
            }
            break;
        case MotionEvent.ACTION_CANCEL:
            if ((System.nanoTime() - startClick) / 1e6 <= CLICK_THRESHOLD) {
                setEnabled(false);
            }
            break;
    }
    return false;
}

private void touchDown(MotionEvent event) {
    mTouchDownListener.onOverLayerTouchDown(event);
}

private void touchMove(MotionEvent event) {
    mTouchMoveListener.onOverLayerTouchMove(event.getX(), event.getY());
}

private void touchUp(MotionEvent event) {
    mTouchUpListener.onOverLayerTouchUp(event);
}

public interface OnOverLayerTouchDownListener {
    void onOverLayerTouchDown(MotionEvent motionEvent);
}

public interface OnOverLayerTouchUpListener {
    void onOverLayerTouchUp(MotionEvent motionEvent);
}

public interface OnOverLayerTouchMoveListener {
    void onOverLayerTouchMove(float x, float y);
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...