package com.jasonchen.microlang.gallery;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import com.jasonchen.microlang.R;
import com.jasonchen.microlang.tasks.MyAsyncTask;
import com.jasonchen.microlang.utils.AnimationRect;
import com.jasonchen.microlang.utils.AnimationUtility;
import com.jasonchen.microlang.utils.SettingUtility;
import com.jasonchen.microlang.utils.Utility;
import com.jasonchen.microlang.utils.image.ImageUtility;
import photoview.PhotoView;
import photoview.PhotoViewAttacher;
/**
* jasonchen
* 2015/04/10
*/
public class GeneralPictureFragment extends Fragment {
private static final int NAVIGATION_BAR_HEIGHT_DP_UNIT = 48;
private static final int IMAGEVIEW_SOFT_LAYER_MAX_WIDTH = 720;
private static final int IMAGEVIEW_SOFT_LAYER_MAX_HEIGHT = 1280;
private PhotoView photoView;
public static final int ANIMATION_DURATION = 300;
public static GeneralPictureFragment newInstance(String path, AnimationRect rect,
boolean animationIn) {
GeneralPictureFragment fragment = new GeneralPictureFragment();
Bundle bundle = new Bundle();
bundle.putString("path", path);
bundle.putParcelable("rect", rect);
bundle.putBoolean("animationIn", animationIn);
fragment.setArguments(bundle);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.gallery_general_layout, container, false);
photoView = (PhotoView) view.findViewById(R.id.animation);
if (SettingUtility.allowClickToCloseGallery()) {
photoView.setOnViewTapListener(new PhotoViewAttacher.OnViewTapListener() {
@Override
public void onViewTap(View view, float x, float y) {
getActivity().onBackPressed();
}
});
}
LongClickListener longClickListener = ((ContainerFragment) getParentFragment())
.getLongClickListener();
photoView.setOnLongClickListener(longClickListener);
final String path = getArguments().getString("path");
boolean animateIn = getArguments().getBoolean("animationIn");
final AnimationRect rect = getArguments().getParcelable("rect");
if (!animateIn) {
new MyAsyncTask<Void, Bitmap, Bitmap>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(Void... params) {
Bitmap bitmap = ImageUtility
.decodeBitmapFromSDCard(path, IMAGEVIEW_SOFT_LAYER_MAX_WIDTH,
IMAGEVIEW_SOFT_LAYER_MAX_HEIGHT);
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
photoView.setImageBitmap(bitmap);
}
}.executeOnIO();
return view;
}
final Bitmap bitmap = ImageUtility
.decodeBitmapFromSDCard(path, IMAGEVIEW_SOFT_LAYER_MAX_WIDTH,
IMAGEVIEW_SOFT_LAYER_MAX_HEIGHT);
photoView.setImageBitmap(bitmap);
final Runnable endAction = new Runnable() {
@Override
public void run() {
Bundle bundle = getArguments();
bundle.putBoolean("animationIn", false);
}
};
photoView.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@SuppressLint("NewApi")
@Override
public boolean onPreDraw() {
if (rect == null) {
photoView.getViewTreeObserver().removeOnPreDrawListener(this);
endAction.run();
return true;
}
final Rect startBounds = new Rect(rect.scaledBitmapRect);
final Rect finalBounds = AnimationUtility
.getBitmapRectFromImageView(photoView);
if (finalBounds == null) {
photoView.getViewTreeObserver().removeOnPreDrawListener(this);
endAction.run();
return true;
}
float startScale = (float) finalBounds.width() / startBounds.width();
if (startScale * startBounds.height() > finalBounds.height()) {
startScale = (float) finalBounds.height() / startBounds.height();
}
int deltaTop = startBounds.top - finalBounds.top;
int deltaLeft = startBounds.left - finalBounds.left;
photoView.setPivotY(
(photoView.getHeight() - finalBounds.height()) / 2);
photoView.setPivotX((photoView.getWidth() - finalBounds.width()) / 2);
photoView.setScaleX(1 / startScale);
photoView.setScaleY(1 / startScale);
photoView.setTranslationX(deltaLeft);
photoView.setTranslationY(deltaTop);
photoView.animate().translationY(0).translationX(0)
.scaleY(1)
.scaleX(1).setDuration(ANIMATION_DURATION)
.setInterpolator(
new AccelerateDecelerateInterpolator())
.withEndAction(endAction);
AnimatorSet animationSet = new AnimatorSet();
animationSet.setDuration(ANIMATION_DURATION);
animationSet
.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.playTogether(ObjectAnimator.ofFloat(photoView,
"clipBottom",
AnimationRect.getClipBottom(rect, finalBounds), 0));
animationSet.playTogether(ObjectAnimator.ofFloat(photoView,
"clipRight",
AnimationRect.getClipRight(rect, finalBounds), 0));
animationSet.playTogether(ObjectAnimator.ofFloat(photoView,
"clipTop", AnimationRect.getClipTop(rect, finalBounds), 0));
animationSet.playTogether(ObjectAnimator.ofFloat(photoView,
"clipLeft", AnimationRect.getClipLeft(rect, finalBounds), 0));
animationSet.start();
photoView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
return view;
}
public void animationExit(ObjectAnimator backgroundAnimator) {
if (Math.abs(photoView.getScale() - 1.0f) > 0.1f) {
photoView.setScale(1, true);
return;
}
getActivity().overridePendingTransition(0, 0);
animateClose(backgroundAnimator);
}
@SuppressLint("NewApi")
private void animateClose(ObjectAnimator backgroundAnimator) {
AnimationRect rect = getArguments().getParcelable("rect");
if (rect == null) {
photoView.animate().alpha(0);
backgroundAnimator.start();
return;
}
final Rect startBounds = rect.scaledBitmapRect;
final Rect finalBounds = AnimationUtility.getBitmapRectFromImageView(photoView);
if (finalBounds == null) {
photoView.animate().alpha(0);
backgroundAnimator.start();
return;
}
if (Utility.isDevicePort() != rect.isScreenPortrait) {
photoView.animate().alpha(0);
backgroundAnimator.start();
return;
}
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
startScale = (float) startBounds.height() / finalBounds.height();
} else {
startScale = (float) startBounds.width() / finalBounds.width();
}
final float startScaleFinal = startScale;
int deltaTop = startBounds.top - finalBounds.top;
int deltaLeft = startBounds.left - finalBounds.left;
photoView.setPivotY((photoView.getHeight() - finalBounds.height()) / 2);
photoView.setPivotX((photoView.getWidth() - finalBounds.width()) / 2);
photoView.animate().translationX(deltaLeft).translationY(deltaTop)
.scaleY(startScaleFinal)
.scaleX(startScaleFinal).setDuration(ANIMATION_DURATION)
.setInterpolator(new AccelerateDecelerateInterpolator())
.withEndAction(new Runnable() {
@Override
public void run() {
photoView.animate().alpha(0.0f).setDuration(200).withEndAction(
new Runnable() {
@Override
public void run() {
}
});
}
});
AnimatorSet animationSet = new AnimatorSet();
animationSet.setDuration(ANIMATION_DURATION);
animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.playTogether(backgroundAnimator);
animationSet.playTogether(ObjectAnimator.ofFloat(photoView,
"clipBottom", 0,
AnimationRect.getClipBottom(rect, finalBounds)));
animationSet.playTogether(ObjectAnimator.ofFloat(photoView,
"clipRight", 0,
AnimationRect.getClipRight(rect, finalBounds)));
animationSet.playTogether(ObjectAnimator.ofFloat(photoView,
"clipTop", 0, AnimationRect.getClipTop(rect, finalBounds)));
animationSet.playTogether(ObjectAnimator.ofFloat(photoView,
"clipLeft", 0, AnimationRect.getClipLeft(rect, finalBounds)));
animationSet.start();
}
}