Skip to content

Commit

Permalink
Migrate to androidx, add setAnimationDuration API
Browse files Browse the repository at this point in the history
  • Loading branch information
natario1 committed Dec 12, 2018
1 parent b40681b commit a87a460
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 43 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Expand Up @@ -21,6 +21,6 @@ android {
}

dependencies {
implementation "com.android.support:appcompat-v7:$supportLibVersion"
implementation "androidx.appcompat:appcompat:$supportLibVersion"
implementation project(':library')
}
Expand Up @@ -10,11 +10,11 @@
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.AttrRes;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.AttrRes;
import androidx.annotation.ColorInt;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
Expand Down
Expand Up @@ -5,9 +5,9 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
Expand Down
@@ -1,6 +1,5 @@
package com.otaliastudios.zoom.demo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
Expand All @@ -9,6 +8,8 @@
import com.otaliastudios.zoom.ZoomLayout;
import com.otaliastudios.zoom.ZoomLogger;

import androidx.appcompat.app.AppCompatActivity;


public class MainActivity extends AppCompatActivity {

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Expand Up @@ -23,7 +23,7 @@ allprojects {
ext {
// Updating? Update travis.yml.
compileSdkVersion = 28
supportLibVersion = '28.0.0'
supportLibVersion = '1.0.0'
minSdkVersion = 16
targetSdkVersion = 28
}
Expand Down
3 changes: 3 additions & 0 deletions gradle.properties
Expand Up @@ -11,6 +11,9 @@
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m

android.enableJetifier=true
android.useAndroidX=true

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
Expand Down
2 changes: 1 addition & 1 deletion library/build.gradle
Expand Up @@ -29,7 +29,7 @@ android {
}

dependencies {
api "com.android.support:support-annotations:$supportLibVersion"
api "androidx.annotation:annotation:$supportLibVersion"
}


Expand Down
10 changes: 9 additions & 1 deletion library/src/main/java/com/otaliastudios/zoom/ZoomApi.java
@@ -1,7 +1,7 @@
package com.otaliastudios.zoom;

import android.graphics.Matrix;
import android.support.annotation.IntDef;
import androidx.annotation.IntDef;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand Down Expand Up @@ -273,4 +273,12 @@ public interface ZoomApi {
*/
@AbsolutePan
float getPanY();

/**
* Sets the duration of animations triggered by zoom and pan APIs.
* Defaults to {@link ZoomEngine#DEFAULT_ANIMATION_DURATION}.
*
* @param duration new animation duration
*/
void setAnimationDuration(long duration);
}
37 changes: 23 additions & 14 deletions library/src/main/java/com/otaliastudios/zoom/ZoomEngine.java
Expand Up @@ -5,8 +5,8 @@
import android.graphics.Matrix;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
Expand Down Expand Up @@ -40,16 +40,18 @@
*/
public final class ZoomEngine implements ZoomApi {

private static final String TAG = ZoomEngine.class.getSimpleName();
public static final long DEFAULT_ANIMATION_DURATION = 280;
// TODO Make public, add API. Use androidx.Interpolator?
private static final Interpolator INTERPOLATOR = new AccelerateDecelerateInterpolator();
private static final int ANIMATION_DURATION = 280;

private static final String TAG = ZoomEngine.class.getSimpleName();
private static final ZoomLogger LOG = ZoomLogger.create(TAG);

/**
* An interface to listen for updates in the inner matrix. This will be called
* typically on animation frames.
*/
interface Listener {
public interface Listener {

/**
* Notifies that the inner matrix was updated. The passed matrix can be changed,
Expand Down Expand Up @@ -141,6 +143,7 @@ public final void onUpdate(@NonNull ZoomEngine engine, @NonNull Matrix matrix) {
private boolean mClearAnimation;
private OverScroller mFlingScroller;
private int[] mTemp = new int[3];
private long mAnimationDuration = DEFAULT_ANIMATION_DURATION;

private ScaleGestureDetector mScaleDetector;
private GestureDetector mFlingDragDetector;
Expand Down Expand Up @@ -422,7 +425,7 @@ public void setContentSize(float width, float height, boolean applyTransformatio
*/
@SuppressWarnings("WeakerAccess")
public void setContainerSize(float width, float height) {
setContentSize(width, height, false);
setContainerSize(width, height, false);
}

/**
Expand Down Expand Up @@ -455,7 +458,7 @@ private void onSizeChanged(boolean applyTransformation) {
|| mContainerWidth <= 0
|| mContainerHeight <= 0) return;

LOG.i("onSizeChanged:", "containerWidth:", mContainerWidth,
LOG.w("onSizeChanged:", "containerWidth:", mContainerWidth,
"containerHeight:", mContainerHeight,
"contentWidth:", mContentRect.width(),
"contentHeight:", mContentRect.height());
Expand All @@ -464,15 +467,16 @@ private void onSizeChanged(boolean applyTransformation) {
// if we don't want to apply it, we must do extra computations to keep the appearance unchanged.
setState(NONE);
boolean apply = !mInitialized || applyTransformation;
LOG.w("onSizeChanged: will apply?", apply, "transformation?", mTransformation);
if (apply) {
// First time. Apply base zoom, dispatch first event and return.
mBaseZoom = computeBaseZoom();
mMatrix.setScale(mBaseZoom, mBaseZoom);
mMatrix.mapRect(mTransformedRect, mContentRect);
mZoom = 1f;
LOG.i("onSizeChanged:", "apply:", "newBaseZoom:", mBaseZoom, "newZoom:", mZoom);
LOG.i("onSizeChanged: newBaseZoom:", mBaseZoom, "newZoom:", mZoom);
@Zoom float newZoom = ensureScaleBounds(mZoom, false);
LOG.i("onSizeChanged:", "apply:", "scaleBounds:", "we need a zoom correction of", (newZoom - mZoom));
LOG.i("onSizeChanged: scaleBounds:", "we need a zoom correction of", (newZoom - mZoom));
if (newZoom != mZoom) applyZoom(newZoom, false);

// pan based on transformation gravity.
Expand All @@ -491,12 +495,12 @@ private void onSizeChanged(boolean applyTransformation) {
// we must do extra work: recompute the baseZoom (since size changed, it makes no sense)
// but also compute a new zoom such that the real zoom is kept unchanged.
// So, this method triggers no Matrix updates.
LOG.i("onSizeChanged:", "Trying to keep real zoom to", getRealZoom());
LOG.i("onSizeChanged:", "oldBaseZoom:", mBaseZoom, "oldZoom:" + mZoom);
LOG.i("onSizeChanged: Trying to keep real zoom to", getRealZoom());
LOG.i("onSizeChanged: oldBaseZoom:", mBaseZoom, "oldZoom:" + mZoom);
@RealZoom float realZoom = getRealZoom();
mBaseZoom = computeBaseZoom();
mZoom = realZoom / mBaseZoom;
LOG.i("onSizeChanged:", "newBaseZoom:", mBaseZoom, "newZoom:", mZoom);
LOG.i("onSizeChanged: newBaseZoom:", mBaseZoom, "newZoom:", mZoom);

// Now sync the content rect with the current matrix since we are trying to keep it.
// This is to have consistent values for other calls here.
Expand All @@ -505,7 +509,7 @@ private void onSizeChanged(boolean applyTransformation) {
// If the new zoom value is invalid, though, we must bring it to the valid place.
// This is a possible matrix update.
@Zoom float newZoom = ensureScaleBounds(mZoom, false);
LOG.i("onSizeChanged:", "wasAlready:", "scaleBounds:", "we need a zoom correction of", (newZoom - mZoom));
LOG.i("onSizeChanged: scaleBounds:", "we need a zoom correction of", (newZoom - mZoom));
if (newZoom != mZoom) applyZoom(newZoom, false);

// If there was any, pan should be kept. I think there's nothing to do here:
Expand Down Expand Up @@ -1218,8 +1222,13 @@ public void run() {
}
}

@Override
public void setAnimationDuration(long duration) {
mAnimationDuration = duration;
}

private float interpolateAnimationTime(long delta) {
float time = Math.min(1, (float) delta / (float) ANIMATION_DURATION);
float time = Math.min(1, (float) delta / (float) mAnimationDuration);
return INTERPOLATOR.getInterpolation(time);
}

Expand Down
57 changes: 45 additions & 12 deletions library/src/main/java/com/otaliastudios/zoom/ZoomImageView.java
Expand Up @@ -3,13 +3,15 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.ImageView;
Expand Down Expand Up @@ -74,32 +76,52 @@ public ZoomImageView(@NonNull Context context, @Nullable AttributeSet attrs, @At

@Override
public void setImageDrawable(@Nullable Drawable drawable) {
super.setImageDrawable(drawable);
init();
}

private void init() {
Drawable drawable = getDrawable();
if (drawable != null) {
mEngine.setContentSize(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mEngine.setContentSize(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
}
super.setImageDrawable(drawable);
}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
return mEngine.onTouchEvent(ev) || super.onTouchEvent(ev);
}

@Override
public void onUpdate(@NonNull ZoomEngine engine, @NonNull Matrix matrix) {
// matrix.getValues(mTemp);
// Log.e("ZoomEngineDEBUG", "View - Received update, matrix scale = " + mTemp[Matrix.MSCALE_X]);
mMatrix.set(matrix);
setImageMatrix(mMatrix);

awakenScrollBars();
}

@Override
public void onIdle(@NonNull ZoomEngine engine) {
public void onIdle(@NonNull ZoomEngine engine) { }

private boolean isInSharedElementTransition() {
return getWidth() != getMeasuredWidth() || getHeight() != getMeasuredHeight();
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
/* Log.e("ZoomEngineDEBUG", "View - dispatching container size" +
" width: " + getWidth() + ", height:" + getHeight() +
" - different?" + isInSharedElementTransition()); */
mEngine.setContainerSize(getWidth(), getHeight(), true);
}

@Override
protected void onDraw(Canvas canvas) {
if (isInSharedElementTransition()) {
// The framework will often change our matrix between onUpdate and onDraw, leaving us with
// a bad first frame that makes a noticeable flash. Replace the matrix values with our own.
setImageMatrix(mMatrix);
}
super.onDraw(canvas);
}

@Override
Expand Down Expand Up @@ -396,5 +418,16 @@ public float getPanY() {
return getEngine().getPanY();
}

/**
* Sets the duration of animations triggered by zoom and pan APIs.
* Defaults to {@link ZoomEngine#DEFAULT_ANIMATION_DURATION}.
*
* @param duration new animation duration
*/
@Override
public void setAnimationDuration(long duration) {
getEngine().setAnimationDuration(duration);
}

//endregion
}
17 changes: 14 additions & 3 deletions library/src/main/java/com/otaliastudios/zoom/ZoomLayout.java
Expand Up @@ -5,9 +5,9 @@
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
Expand Down Expand Up @@ -494,5 +494,16 @@ public float getPanY() {
return getEngine().getPanY();
}

/**
* Sets the duration of animations triggered by zoom and pan APIs.
* Defaults to {@link ZoomEngine#DEFAULT_ANIMATION_DURATION}.
*
* @param duration new animation duration
*/
@Override
public void setAnimationDuration(long duration) {
getEngine().setAnimationDuration(duration);
}

//endregion
}
@@ -1,6 +1,6 @@
package com.otaliastudios.zoom;

import android.support.annotation.IntDef;
import androidx.annotation.IntDef;
import android.util.Log;

import java.lang.annotation.Retention;
Expand Down

0 comments on commit a87a460

Please sign in to comment.