你好!谢谢您的阅读。
我一直在寻找正确创建特定尺寸(用户屏幕尺寸的5倍)的多向可滚动 Android布局的方法。 猛冲(和平移),也可以放大。
要注意,让孩子(ConstraintLayout)成为所需大小(用户屏幕的5倍)不是不是问题。
很明显,我在网上找到了很多答案,以了解如何通过不同的方式来实现此目的。最初,我将发布迄今为止尚未尝试的所有不同集成,直到遇到 Oded's solution 。在这一过程中,所有无法正常工作的事物都可以正常工作。
这意味着:
这是一个极大的解脱,因为修改不同的已完成但缺乏集成(主要用于解决边界和缩放问题)的工作已经花费了几天。
我建议以后遇到类似问题的任何人都可以使用此集成。
在任何情况下,都存在一些问题,包括:屏幕方向更改后返回(0,0),无两次轻按缩放和无晃动。我认为要解决前两个问题并不困难,但是,这第三个问题很成问题。我希望用户能够自由查看这个大区域。没有能力,将使应用程序的移动速度慢于可取的速度。
我已经尝试了不同的方法,例如,将Scroller类与GestureDetector一起使用,使用“ Flinger”可运行类(包含Scroller),使用某种形式的Choreographer,等等。
我一直无法使其正常工作,解决方案通常会完全破坏此布局进行滚动的方式(例如,我注意到scrollX从未改变,并且没有scrollTo函数存在(由mPosX替换)。通常,在这里似乎无法使用添加Flinging的正确解决方案,并且在某些情况下,实现使滚动条从应有的位置移动了数千个单位。
Here是我对Odid解决方案的备份,唯一的更改是为避免Android Studio警告而进行的细微调整。
摘要(必填):
@Override
public boolean onTouchEvent(MotionEvent ev) {
mOnTouchEventWorkingArray[0] = ev.getX();
mOnTouchEventWorkingArray[1] = ev.getY();
mOnTouchEventWorkingArray = scaledPointsToScreenPoints(mOnTouchEventWorkingArray);
ev.setLocation(mOnTouchEventWorkingArray[0], mOnTouchEventWorkingArray[1]);
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
if (mIsScaling && ev.getPointerCount() == 1) {
// Don't move during a QuickScale.
mLastTouchX = x;
mLastTouchY = y;
break;
}
float dx = x - mLastTouchX;
float dy = y - mLastTouchY;
float[] topLeft = {0f, 0f};
float[] bottomRight = {getWidth(), getHeight()};
/*
* Corners of the view in screen coordinates, so dx/dy should not be allowed to
* push these beyond the canvas bounds.
*/
float[] scaledTopLeft = screenPointsToScaledPoints(topLeft);
float[] scaledBottomRight = screenPointsToScaledPoints(bottomRight);
dx = Math.min(Math.max(dx, scaledBottomRight[0] - mCanvasWidth), scaledTopLeft[0]);
dy = Math.min(Math.max(dy, scaledBottomRight[1] - mCanvasHeight), scaledTopLeft[1]);
mPosX += dx;
mPosY += dy;
mTranslateMatrix.preTranslate(dx, dy);
mTranslateMatrix.invert(mTranslateMatrixInverse);
mLastTouchX = x;
mLastTouchY = y;
invalidate();
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
// Extract the index of the pointer that left the touch sensor
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
非常感谢您的帮助。