Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/disable zoom #31

Merged
merged 5 commits into from
Jun 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ A container for view hierarchies that can be panned or zoomed.
android:layout_height="match_parent"
app:overScrollHorizontal="true"
app:overScrollVertical="true"
app:horizontalPanEnabled="true"
app:verticalPanEnabled="true"
app:overPinchable="true"
app:zoomEnabled="true"
app:minZoom="0.7"
app:minZoomType="zoom"
app:maxZoom="3.0"
Expand Down Expand Up @@ -87,7 +90,10 @@ An `ImageView` implementation to control pan and zoom over its Drawable or Bitma
android:layout_height="match_parent"
app:overScrollHorizontal="true"
app:overScrollVertical="true"
app:horizontalPanEnabled="true"
app:verticalPanEnabled="true"
app:overPinchable="true"
app:zoomEnabled="true"
app:minZoom="0.7"
app:minZoomType="zoom"
app:maxZoom="3.0"
Expand Down Expand Up @@ -185,6 +191,7 @@ will make more sense than the other - e. g., in a PDF viewer, you might want to
|`zoomBy(float, boolean)`|Applies the given factor to the current zoom, animating if needed. OK for both types.|`-`|
|`zoomIn()`|Applies a small, animated zoom-in.|`-`|
|`zoomOut()`|Applies a small, animated zoom-out.|`-`|
|`setZoomEnabled(boolean)`|If true, the content will be allowed to zoom in and out by user input.|`true`|

The `moveTo(float, float, float, boolean)` API will let you animate both zoom and [pan](#pan) at the same time.

Expand All @@ -204,6 +211,8 @@ In any case the current scale is not considered, so your system won't change if
|`getPanY()`|Returns the current vertical pan.|`-`|
|`setOverScrollHorizontal(boolean)`|If true, the content will be allowed to pan outside its horizontal bounds, then return to its position.|`true`|
|`setOverScrollVertical(boolean)`|If true, the content will be allowed to pan outside its vertical bounds, then return to its position.|`true`|
|`setHorizontalPanEnabled(boolean)`|If true, the content will be allowed to pan **horizontally** by user input.|`true`|
|`setVerticalPanEnabled(boolean)`|If true, the content will be allowed to pan **vertically** by user input.|`true`|
|`panTo(float, float, boolean)`|Pans to the given values, animating if needed.|`-`|
|`panBy(float, float, boolean)`|Applies the given deltas to the current pan, animating if needed.|`-`|

Expand Down
46 changes: 24 additions & 22 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,53 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">

<com.otaliastudios.zoom.ZoomLayout
android:layout_weight="1"
android:id="@+id/zoom_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:hasClickableChildren="true">
android:layout_weight="1"
app:hasClickableChildren="true"
app:horizontalPanEnabled="true"
app:verticalPanEnabled="true"
app:zoomEnabled="true">

<com.otaliastudios.zoom.demo.ColorGridView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content" />

</com.otaliastudios.zoom.ZoomLayout>

<com.otaliastudios.zoom.ZoomImageView
android:layout_weight="1"
android:id="@+id/zoom_image"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="0dp"/>
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="gone" />

<LinearLayout
android:background="@color/colorAccent"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:orientation="horizontal">

<Button
android:text="View hierarchy"
android:id="@+id/show_zl"
android:background="@null"
android:layout_weight="0.5"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:background="@null"
android:text="View hierarchy" />

<Button
android:text="Image"
android:id="@+id/show_ziv"
android:background="@null"
android:layout_weight="0.5"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:background="@null"
android:text="Image" />

</LinearLayout>

Expand Down
86 changes: 51 additions & 35 deletions library/src/main/java/com/otaliastudios/zoom/ZoomApi.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
package com.otaliastudios.zoom;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.IntDef;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.OverScroller;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand All @@ -24,16 +13,20 @@
public interface ZoomApi {

@Retention(RetentionPolicy.SOURCE)
@interface RealZoom {}
@interface RealZoom {
}

@Retention(RetentionPolicy.SOURCE)
@interface Zoom {}
@interface Zoom {
}

@Retention(RetentionPolicy.SOURCE)
@interface AbsolutePan {}
@interface AbsolutePan {
}

@Retention(RetentionPolicy.SOURCE)
@interface ScaledPan {}
@interface ScaledPan {
}

/**
* Flag for zoom constraints and settings.
Expand All @@ -57,7 +50,8 @@ public interface ZoomApi {

@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_ZOOM, TYPE_REAL_ZOOM})
@interface ZoomType {}
@interface ZoomType {
}

/**
* Constant for {@link #setTransformation(int, int)}.
Expand All @@ -81,7 +75,8 @@ public interface ZoomApi {

@Retention(RetentionPolicy.SOURCE)
@IntDef({TRANSFORMATION_CENTER_INSIDE, TRANSFORMATION_CENTER_CROP, TRANSFORMATION_NONE})
@interface Transformation {}
@interface Transformation {
}

/**
* Controls whether the content should be over-scrollable horizontally.
Expand All @@ -101,6 +96,20 @@ public interface ZoomApi {
*/
void setOverScrollVertical(boolean overScroll);

/**
* Controls whether horizontal panning using gestures is enabled.
*
* @param enabled true enables horizontal panning, false disables it
*/
void setHorizontalPanEnabled(boolean enabled);

/**
* Controls whether vertical panning using gestures is enabled.
*
* @param enabled true enables vertical panning, false disables it
*/
void setVerticalPanEnabled(boolean enabled);

/**
* Controls whether the content should be overPinchable.
* If it is, pinch events can change the zoom outside the safe bounds,
Expand All @@ -110,13 +119,20 @@ public interface ZoomApi {
*/
void setOverPinchable(boolean overPinchable);

/**
* Controls whether zoom using pinch gesture is enabled or not.
*
* @param enabled true enables zooming, false disables it
*/
void setZoomEnabled(boolean enabled);

/**
* Sets the base transformation to be applied to the content.
* Defaults to {@link #TRANSFORMATION_CENTER_INSIDE} with {@link android.view.Gravity#CENTER},
* which means that the content will be zoomed so that it fits completely inside the container.
*
* @param transformation the transformation type
* @param gravity the transformation gravity. Might be ignored for some transformations
* @param gravity the transformation gravity. Might be ignored for some transformations
*/
void setTransformation(@Transformation int transformation, int gravity);

Expand All @@ -125,9 +141,9 @@ public interface ZoomApi {
* Zoom might not be the actual matrix scale, see {@link #getZoom()} and {@link #getRealZoom()}.
* The coordinates are referred to the content size so they do not depend on current zoom.
*
* @param zoom the desired zoom value
* @param x the desired left coordinate
* @param y the desired top coordinate
* @param zoom the desired zoom value
* @param x the desired left coordinate
* @param y the desired top coordinate
* @param animate whether to animate the transition
*/
void moveTo(@Zoom float zoom, @AbsolutePan float x, @AbsolutePan float y, boolean animate);
Expand All @@ -136,21 +152,21 @@ public interface ZoomApi {
* Pans the content until the top-left coordinates match the given x-y
* values. These are referred to the content size so they do not depend on current zoom.
*
* @param x the desired left coordinate
* @param y the desired top coordinate
* @param x the desired left coordinate
* @param y the desired top coordinate
* @param animate whether to animate the transition
*/
void panTo(@AbsolutePan float x, @AbsolutePan float y, boolean animate);

/**
* Pans the content by the given quantity in dx-dy values.
* These are referred to the content size so they do not depend on current zoom.
*
* <p>
* In other words, asking to pan by 1 pixel might result in a bigger pan, if the content
* was zoomed in.
*
* @param dx the desired delta x
* @param dy the desired delta y
* @param dx the desired delta x
* @param dy the desired delta y
* @param animate whether to animate the transition
*/
void panBy(@AbsolutePan float dx, @AbsolutePan float dy, boolean animate);
Expand All @@ -159,7 +175,7 @@ public interface ZoomApi {
* Zooms to the given scale. This might not be the actual matrix zoom,
* see {@link #getZoom()} and {@link #getRealZoom()}.
*
* @param zoom the new scale value
* @param zoom the new scale value
* @param animate whether to animate the transition
*/
void zoomTo(@Zoom float zoom, boolean animate);
Expand All @@ -168,7 +184,7 @@ public interface ZoomApi {
* Applies the given factor to the current zoom.
*
* @param zoomFactor a multiplicative factor
* @param animate whether to animate the transition
* @param animate whether to animate the transition
*/
void zoomBy(float zoomFactor, boolean animate);

Expand All @@ -186,7 +202,7 @@ public interface ZoomApi {
* Animates the actual matrix zoom to the given value.
*
* @param realZoom the new real zoom value
* @param animate whether to animate the transition
* @param animate whether to animate the transition
*/
void realZoomTo(float realZoom, boolean animate);

Expand All @@ -195,10 +211,10 @@ public interface ZoomApi {
* If {@link #setOverPinchable(boolean)} is set to true, this can be over-pinched
* for a brief time.
*
* @param maxZoom the max zoom
* @param type the constraint mode
* @see #getZoom()
* @see #getRealZoom()
* @param maxZoom the max zoom
* @param type the constraint mode
*/
void setMaxZoom(float maxZoom, @ZoomType int type);

Expand All @@ -207,24 +223,24 @@ public interface ZoomApi {
* If {@link #setOverPinchable(boolean)} is set to true, this can be over-pinched
* for a brief time.
*
* @param minZoom the min zoom
* @param type the constraint mode
* @see #getZoom()
* @see #getRealZoom()
* @param minZoom the min zoom
* @param type the constraint mode
*/
void setMinZoom(float minZoom, @ZoomType int type);

/**
* Gets the current zoom value, which can be used as a reference when calling
* {@link #zoomTo(float, boolean)} or {@link #zoomBy(float, boolean)}.
*
* <p>
* This can be different than the actual scale you get in the matrix, because at startup
* we apply a base zoom to respect the "center inside" policy.
* All zoom calls, including min zoom and max zoom, refer to this axis, where zoom is set to 1
* right after the initial transformation.
*
* @see #getRealZoom()
* @return the current zoom
* @see #getRealZoom()
*/
@Zoom
float getZoom();
Expand Down