我有以下情况:
ZoomAndPanLayout
|
+---> ImageView
|
+---> FrameLayout (DragLayer)
|
+---> One or more controls. A view with a circle drawn on it.
有一些小问题,因为我现在不在乎屏幕绑定,ZoomAndPanLayout可以工作。我是这样实现ZoomAndPan的:
public class ZoomAndPanLayout extends FrameLayout {
//region Constants
public static final float DEFAULT_MIN_SCALE_FACTOR = 1.0f;
public static final float DEFAULT_MAX_SCALE_FACTOR = 5.0f;
// endregion Constants
// region Fields
private float translationX = 0;
private float translationY = 0;
private float pivotX = 0;
private float pivotY = 0;
private float oldX;
private float oldY;
private float scaleFactor = 1.0f;
private float minScaleFactor = ZoomAndPanLayout.DEFAULT_MIN_SCALE_FACTOR;
private float maxScaleFactor = ZoomAndPanLayout.DEFAULT_MAX_SCALE_FACTOR;
private ScaleGestureDetector scaleGestureDetector = null;
// endregion Fields
// region Constructor
public ZoomAndPanLayout(Context context) {
super(context);
this.initialize(context);
}
public ZoomAndPanLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.initialize(context);
}
public ZoomAndPanLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.initialize(context);
}
private void initialize(Context context) {
this.scaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureListener());
}
// endregion Constructor
@Override
public boolean onTouchEvent(MotionEvent event) {
this.scaleGestureDetector.onTouchEvent(event);
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
this.oldX = event.getX();
this.oldY = event.getY();
break;
}
case MotionEvent.ACTION_MOVE:
{
if (!this.scaleGestureDetector.isInProgress())
{
float x = event.getX();
float y = event.getY();
float deltaX = x - this.oldX;
float deltaY = y - this.oldY;
this.translationX += deltaX;
this.translationY += deltaY;
this.applyTransformations();
this.oldX = x;
this.oldY = y;
}
}
}
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return this.scaleGestureDetector.onTouchEvent(event);
}
private void applyTransformations() {
final View child = this.getChildAt(0);
if (child != null)
{
child.setPivotX(this.pivotX);
child.setPivotY(this.pivotY);
child.setScaleX(this.scaleFactor);
child.setScaleY(this.scaleFactor);
// TODO: bound child to screen limits
child.setTranslationX(this.translationX);
child.setTranslationY(this.translationY);
}
}
public Rect getChildRect() {
View child = this.getChildAt(0);
if (child != null)
{
Rect outRect = new Rect();
outRect.right = (int) (child.getWidth() * child.getScaleX());
outRect.bottom = (int) (child.getHeight() * child.getScaleY());
int[] location = new int[2];
child.getLocationOnScreen(location);
outRect.offset(location[0], location[1]);
return outRect;
}
else
{
return new Rect(0, 0, 0, 0);
}
}
// region Private Inner Enums, Interfaces and Classes
private class ScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
private ZoomAndPanLayout upper = ZoomAndPanLayout.this;
@Override
public boolean onScale(ScaleGestureDetector detector) {
float newScaleFactor = detector.getScaleFactor();
float originalScaleFactor = upper.scaleFactor;
upper.scaleFactor *= newScaleFactor;
// Bound the scaleFactor to the min and max limits
if (upper.scaleFactor >= upper.maxScaleFactor)
{
upper.scaleFactor = upper.maxScaleFactor;
newScaleFactor = upper.maxScaleFactor / originalScaleFactor;
}
else if (upper.scaleFactor * newScaleFactor <= upper.minScaleFactor)
{
upper.scaleFactor = upper.minScaleFactor;
newScaleFactor = upper.minScaleFactor / originalScaleFactor;
}
// set pivot
View child = upper.getChildAt(0);
if (child != null)
{
if (newScaleFactor * child.getWidth() * upper.scaleFactor <= originalScaleFactor * child.getWidth()
|| newScaleFactor * child.getHeight() * upper.scaleFactor <= originalScaleFactor * child.getWidth())
{
upper.pivotX = newScaleFactor * child.getWidth() / 2;
upper.pivotY = newScaleFactor * child.getHeight() / 2;
}
else
{
upper.pivotX = detector.getFocusX();
upper.pivotY = detector.getFocusY();
}
}
upper.applyTransformations();
return true;
}
}
// endregion Private Inner Enums, Interfaces and Classes
}
当我创建DragLayer的每个子级时,我会为它们分配一个OnLongClickListener,但该死的东西不会启动。当我长时间单击DragLayer的任何子对象时。
任何想法我如何使用我对ZoomAndPanLayout的想法或任何想法来实现这一点。如果你问自己为什么我需要ZoomAndPanLayout,那是因为我必须能够缩放和平移任何布局,而不仅仅是ImageView。
知道吗?
可能是因为您在onTouchEvent
方法中返回了true
。当返回true
时,它消耗了一个事件,并且子级不会收到自己的onTouchEvent
。
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return this.scaleGestureDetector.onTouchEvent(event);
}
总是返回CCD_ 6,并且它还阻止子级接收事件。