Я все,
мое приложение состоит из:
диаграмма
Каждый фрагмент загружается в контейнер активности.
Это действие имеет вид (оверлей), который занимает 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);
}
}