How does the games produce an activity exceeding the screen size?
-
How do the games have a large size of the screen, with the possibility of clothing and climaticity on its elements?
All that has been found on this topic is the copying of a part of a large picture in some Rectangle of the limited area of withdrawal, but the approach is losing the climaticity of a large activity and the elements of its location.
If you don't invent a bicycle, who can tell us how to do it?
-
public class ZoomLayout extends FrameLayout implements ScaleGestureDetector.OnScaleGestureListener { private enum Mode { NONE, DRAG, ZOOM } public static boolean DRAGGING =false; private static final float MIN_ZOOM = 1.0f; private static final float MAX_ZOOM = 4.0f; private Mode mode = Mode.NONE; private float scale = 1.0f; private float lastScaleFactor = 0f; // Where the finger first touches the screen private float startX = 0f; private float startY = 0f; // How much to translate the canvas private float dx = 0f; private float dy = 0f; private float prevDx = 0f; private float prevDy = 0f; ScaleGestureDetector scaleDetector; public ZoomLayout(Context context) { super(context); init(context); } public ZoomLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public ZoomLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean upper = super.onInterceptTouchEvent(ev); DRAGGING = false; if (!upper) { switch (ev.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: if (scale > MIN_ZOOM) { mode = Mode.DRAG; startX = ev.getX() - prevDx; startY = ev.getY() - prevDy; } break; case MotionEvent.ACTION_MOVE: DRAGGING = true; if (mode == Mode.DRAG) { dx = ev.getX() - startX; dy = ev.getY() - startY; } break; case MotionEvent.ACTION_POINTER_DOWN: mode = Mode.ZOOM; break; case MotionEvent.ACTION_POINTER_UP: mode = Mode.DRAG; break; case MotionEvent.ACTION_UP: mode = Mode.NONE; prevDx = dx; prevDy = dy; break; } scaleDetector.onTouchEvent(ev); if ((mode == Mode.DRAG && scale >= MIN_ZOOM) || mode == Mode.ZOOM) { rescale(); } } return upper; } private void init(Context context) { scaleDetector = new ScaleGestureDetector(context, this); this.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { return true; } }); } public void setScale(float scale) { this.scale = scale; } public void rescale() { for (int i = 0; i < getChildCount(); i++) { getParent().requestDisallowInterceptTouchEvent(true); float maxDx = (child(i).getWidth() - (child(i).getWidth() / scale)) / 2 * scale; float maxDy = (child(i).getHeight() - (child(i).getHeight() / scale)) / 2 * scale; dx = Math.min(Math.max(dx, -maxDx), maxDx); dy = Math.min(Math.max(dy, -maxDy), maxDy); applyScaleAndTranslation(i); } } @Override public boolean onScaleBegin(ScaleGestureDetector scaleDetector) { return true; } @Override public boolean onScale(ScaleGestureDetector scaleDetector) { float scaleFactor = scaleDetector.getScaleFactor(); if (lastScaleFactor == 0 || (Math.signum(scaleFactor) == Math.signum(lastScaleFactor))) { scale *= scaleFactor; scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM)); lastScaleFactor = scaleFactor; } else { lastScaleFactor = 0; } return true; } @Override public void onScaleEnd(ScaleGestureDetector scaleDetector) { } private void applyScaleAndTranslation(int i) { child(i).setScaleX(scale); child(i).setScaleY(scale); child(i).setTranslationX(dx); child(i).setTranslationY(dy); } private View child(int i) { return getChildAt(i); } }