From e86a5622b62f353bd1e6cffc63e3a706b5737313 Mon Sep 17 00:00:00 2001 From: Christophe Beyls Date: Sun, 22 Jan 2017 21:11:07 +0100 Subject: [PATCH] Implement approximate state restoration for PhotoView; fixes #20 --- .../fosdem/widgets/SaveStatePhotoView.java | 107 ++++++++++++++++++ app/src/main/res/layout/fragment_map.xml | 5 +- 2 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/be/digitalia/fosdem/widgets/SaveStatePhotoView.java diff --git a/app/src/main/java/be/digitalia/fosdem/widgets/SaveStatePhotoView.java b/app/src/main/java/be/digitalia/fosdem/widgets/SaveStatePhotoView.java new file mode 100644 index 0000000..9cb8d97 --- /dev/null +++ b/app/src/main/java/be/digitalia/fosdem/widgets/SaveStatePhotoView.java @@ -0,0 +1,107 @@ +package be.digitalia.fosdem.widgets; + +import android.content.Context; +import android.graphics.RectF; +import android.os.Parcel; +import android.os.Parcelable; +import android.support.v4.os.ParcelableCompat; +import android.support.v4.os.ParcelableCompatCreatorCallbacks; +import android.util.AttributeSet; +import android.view.ViewTreeObserver; + +import uk.co.senab.photoview.PhotoView; + +/** + * PhotoView which saves and restores the current scale and approximate position. + */ +public class SaveStatePhotoView extends PhotoView { + + public SaveStatePhotoView(Context context) { + super(context); + } + + public SaveStatePhotoView(Context context, AttributeSet attr) { + super(context, attr); + } + + public SaveStatePhotoView(Context context, AttributeSet attr, int defStyle) { + super(context, attr, defStyle); + } + + @Override + protected Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + ss.scale = getScale(); + final RectF rect = getDisplayRect(); + final float overflowWidth = rect.width() - getWidth(); + if (overflowWidth > 0f) { + ss.pivotX = -rect.left / overflowWidth; + } + final float overflowHeight = rect.height() - getHeight(); + if (overflowHeight > 0f) { + ss.pivotY = -rect.top / overflowHeight; + } + return ss; + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + if (!(state instanceof SavedState)) { + super.onRestoreInstanceState(state); + return; + } + + final SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + + getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @SuppressWarnings("deprecation") + @Override + public void onGlobalLayout() { + float scale = Math.max(ss.scale, getMinimumScale()); + scale = Math.min(scale, getMaximumScale()); + setScale(scale, getWidth() * ss.pivotX, getHeight() * ss.pivotY, false); + getViewTreeObserver().removeGlobalOnLayoutListener(this); + } + }); + } + + public static class SavedState extends BaseSavedState { + float scale = 1f; + float pivotX = 0.5f; + float pivotY = 0.5f; + + public SavedState(Parcelable superState) { + super(superState); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeFloat(scale); + out.writeFloat(pivotX); + out.writeFloat(pivotY); + } + + public static final Parcelable.Creator CREATOR + = ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks() { + @Override + public SavedState createFromParcel(Parcel in, ClassLoader loader) { + return new SavedState(in); + } + + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }); + + SavedState(Parcel in) { + super(in); + scale = in.readFloat(); + pivotX = in.readFloat(); + pivotY = in.readFloat(); + } + } +} diff --git a/app/src/main/res/layout/fragment_map.xml b/app/src/main/res/layout/fragment_map.xml index fb12a3d..b7297b0 100644 --- a/app/src/main/res/layout/fragment_map.xml +++ b/app/src/main/res/layout/fragment_map.xml @@ -1,7 +1,8 @@ - + android:src="@drawable/campusmap"/>