package com.looklook.xinghongfei.looklook.activity;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.Toolbar;
import android.transition.ChangeBounds;
import android.transition.Transition;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.RelativeLayout;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.looklook.xinghongfei.looklook.R;
import com.looklook.xinghongfei.looklook.util.ColorUtils;
import com.looklook.xinghongfei.looklook.util.GlideUtils;
import com.wingsofts.dragphotoview.DragPhotoView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Date;
import butterknife.BindView;
import butterknife.ButterKnife;
import uk.co.senab.photoview.PhotoViewAttacher;
/**
* Created by xinghongfei on 16/8/13.
*/
public class MeiziPhotoDescribeActivity extends AppCompatActivity {
public static final String EXTRA_IMAGE_URL = "image";
private static final float SCRIM_ADJUSTMENT = 0.075f;
private String mImageUrl;
@BindView(R.id.shot)
DragPhotoView mDragPhotoView;
@BindView(R.id.toolbar)
Toolbar mToolbar;
@BindView(R.id.background)
RelativeLayout mRelativeLayout;
private int mOriginLeft;
private int mOriginTop;
private int mOriginHeight;
private int mOriginWidth;
private int mOriginCenterX;
private int mOriginCenterY;
private boolean mIsHidden = false;
private float mTargetHeight;
private float mTargetWidth;
private float mScaleX;
private float mScaleY;
private float mTranslationX;
private float mTranslationY;
private Transition.TransitionListener mListener = new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
// mRelativeLayout.animate()
// .alpha(1f)
// .setDuration(1000L)
// .setInterpolator(new AccelerateInterpolator())
// .start();
}
@Override
public void onTransitionEnd(Transition transition) {
}
@Override
public void onTransitionCancel(Transition transition) {
}
@Override
public void onTransitionPause(Transition transition) {
}
@Override
public void onTransitionResume(Transition transition) {
}
};
private RequestListener loadListener = new RequestListener<String, GlideDrawable>() {
@Override
public boolean onResourceReady(GlideDrawable resource, String model,
Target<GlideDrawable> target, boolean isFromMemoryCache,
boolean isFirstResource) {
final Bitmap bitmap = GlideUtils.getBitmap(resource);
final int twentyFourDip = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
24, MeiziPhotoDescribeActivity.this.getResources().getDisplayMetrics());
Palette.from(bitmap)
.maximumColorCount(3)
.clearFilters() /* by default palette ignore certain hues
(e.g. pure black/white) but we don't want this. */
.setRegion(0, 0, bitmap.getWidth() - 1, twentyFourDip) /* - 1 to work around
https://code.google.com/p/android/issues/detail?id=191013 */
.generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
boolean isDark;
@ColorUtils.Lightness int lightness = ColorUtils.isDark(palette);
if (lightness == ColorUtils.LIGHTNESS_UNKNOWN) {
isDark = ColorUtils.isDark(bitmap, bitmap.getWidth() / 2, 0);
} else {
isDark = lightness == ColorUtils.IS_DARK;
}
// color the status bar. Set a complementary dark color on L,
// light or dark color on M (with matching status bar icons)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int statusBarColor = getWindow().getStatusBarColor();
final Palette.Swatch topColor =
ColorUtils.getMostPopulousSwatch(palette);
if (topColor != null &&
(isDark || Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)) {
statusBarColor = ColorUtils.scrimify(topColor.getRgb(),
isDark, SCRIM_ADJUSTMENT);
}
if (statusBarColor != getWindow().getStatusBarColor()) {
ValueAnimator statusBarColorAnim = ValueAnimator.ofArgb(
getWindow().getStatusBarColor(), statusBarColor);
statusBarColorAnim.addUpdateListener(new ValueAnimator
.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
getWindow().setStatusBarColor(
(int) animation.getAnimatedValue());
}
});
statusBarColorAnim.setDuration(1000L);
statusBarColorAnim.setInterpolator(
new AccelerateInterpolator());
statusBarColorAnim.start();
performEnterAnimation();
}
}
}
});
return false;
}
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target,
boolean isFirstResource) {
return false;
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_picture);
ButterKnife.bind(this);
mToolbar.setNavigationIcon(R.drawable.ic_arrow_back);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
expandImageAndFinish();
}
});
mToolbar.setAlpha(0.3f);
mImageUrl = getIntent().getStringExtra(EXTRA_IMAGE_URL);
Glide.with(this)
.load(mImageUrl)
.centerCrop()
.listener(loadListener)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(mDragPhotoView);
initialPhotoAttacher();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().getSharedElementEnterTransition().addListener(mListener);
getWindow().setSharedElementEnterTransition(new ChangeBounds());
// setStatusColor();
}
}
void initialPhotoAttacher() {
mDragPhotoView.setOnTapListener(new DragPhotoView.OnTapListener() {
@Override
public void onTap(DragPhotoView view) {
finishWithAnimation();
}
});
mDragPhotoView.setOnExitListener(new DragPhotoView.OnExitListener() {
@Override
public void onExit(DragPhotoView view, float x, float y, float w, float h) {
performExitAnimation(view, x, y, w, h);
}
});
mRelativeLayout.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mRelativeLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
mOriginLeft = getIntent().getIntExtra("left", 0);
mOriginTop = getIntent().getIntExtra("top", 0);
mOriginHeight = getIntent().getIntExtra("height", 0);
mOriginWidth = getIntent().getIntExtra("width", 0);
mOriginCenterX = mOriginLeft + mOriginWidth / 2;
mOriginCenterY = mOriginTop + mOriginHeight / 2;
int[] location = new int[2];
final DragPhotoView photoView = mDragPhotoView;
photoView.getLocationOnScreen(location);
mTargetHeight = (float) photoView.getHeight();
mTargetWidth = (float) photoView.getWidth();
mScaleX = (float) mOriginWidth / mTargetWidth;
mScaleY = (float) mOriginHeight / mTargetHeight;
float targetCenterX = location[0] + mTargetWidth / 2;
float targetCenterY = location[1] + mTargetHeight / 2;
mTranslationX = mOriginCenterX - targetCenterX;
mTranslationY = mOriginCenterY - targetCenterY;
photoView.setTranslationX(mTranslationX);
photoView.setTranslationY(mTranslationY);
photoView.setScaleX(mScaleX);
photoView.setScaleY(mScaleY);
mDragPhotoView.setMinScale(mScaleX);
mToolbar.animate()
.alpha(1f)
.setDuration(1000L)
.setInterpolator(new AccelerateInterpolator())
.start();
performEnterAnimation();
}
});
mDragPhotoView.setOnViewTapListener(new PhotoViewAttacher.OnViewTapListener() {
@Override
public void onViewTap(View view, float x, float y) {
hideOrShowToolbar();
}
});
// mDragPhotoView.setOnLongClickListener(new View.OnLongClickListener() {
// @Override
// public boolean onLongClick(View view) {
// new AlertDialog.Builder(MeiziPhotoDescribeActivity.this)
// .setMessage(getString(R.string.save_meizi))
// .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface anInterface, int i) {
// anInterface.dismiss();
// }
// })
// .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface anInterface, int i) {
//
// anInterface.dismiss();
// saveImage();
// }
// }).show();
// return true;
// }
// });
}
private void saveImage() {
File externalStorageDirectory = Environment.getExternalStorageDirectory();
File directory = new File(externalStorageDirectory, "LookLook");
if (!directory.exists())
directory.mkdir();
Bitmap drawingCache = mDragPhotoView.getDrawingCache();
try {
File file = new File(directory, new Date().getTime() + ".jpg");
FileOutputStream fos = new FileOutputStream(file);
drawingCache.compress(Bitmap.CompressFormat.JPEG, 100, fos);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
getApplicationContext().sendBroadcast(intent);
} catch (FileNotFoundException e) {
e.printStackTrace();
Snackbar.make(getCurrentFocus(), "阿偶出错了呢", Snackbar.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().getSharedElementEnterTransition().removeListener(mListener);
}
super.onDestroy();
}
@Override
public void onBackPressed() {
super.onBackPressed();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAfterTransition();
} else {
finish();
}
}
@Override
protected void onResume() {
super.onResume();
mRelativeLayout.animate()
.alpha(1f)
.setDuration(1000L)
.setInterpolator(new AccelerateInterpolator())
.start();
}
protected void hideOrShowToolbar() {
mToolbar.animate()
.translationY(mIsHidden ? 0 : -mToolbar.getHeight())
.setInterpolator(new DecelerateInterpolator(2))
.start();
mIsHidden = !mIsHidden;
}
private void expandImageAndFinish() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAfterTransition();
} else {
finish();
}
}
private void finishWithAnimation() {
final DragPhotoView photoView = mDragPhotoView;
ValueAnimator translateXAnimator = ValueAnimator.ofFloat(0, mTranslationX);
translateXAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
photoView.setX((Float) valueAnimator.getAnimatedValue());
}
});
translateXAnimator.setDuration(300);
translateXAnimator.start();
ValueAnimator translateYAnimator = ValueAnimator.ofFloat(0, mTranslationY);
translateYAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
photoView.setY((Float) valueAnimator.getAnimatedValue());
}
});
translateYAnimator.setDuration(300);
translateYAnimator.start();
ValueAnimator scaleYAnimator = ValueAnimator.ofFloat(1, mScaleY);
scaleYAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
photoView.setScaleY((Float) valueAnimator.getAnimatedValue());
}
});
scaleYAnimator.setDuration(300);
scaleYAnimator.start();
ValueAnimator scaleXAnimator = ValueAnimator.ofFloat(1, mScaleX);
scaleXAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
photoView.setScaleX((Float) valueAnimator.getAnimatedValue());
}
});
scaleXAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
animator.removeAllListeners();
finish();
overridePendingTransition(0, 0);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
scaleXAnimator.setDuration(300);
scaleXAnimator.start();
}
private void performExitAnimation(final DragPhotoView view, float x, float y, float w, float h) {
view.finishAnimationCallBack();
float viewX = mTargetWidth / 2 + x - mTargetWidth * mScaleX / 2;
float viewY = mTargetHeight / 2 + y - mTargetHeight * mScaleY / 2;
view.setX(viewX);
view.setY(viewY);
float centerX = view.getX() + mOriginWidth / 2;
float centerY = view.getY() + mOriginHeight / 2;
float translateX = mOriginCenterX - centerX;
float translateY = mOriginCenterY - centerY;
ValueAnimator translateXAnimator = ValueAnimator.ofFloat(view.getX(), view.getX() + translateX);
translateXAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
view.setX((Float) valueAnimator.getAnimatedValue());
}
});
translateXAnimator.setDuration(300);
translateXAnimator.start();
ValueAnimator translateYAnimator = ValueAnimator.ofFloat(view.getY(), view.getY() + translateY);
translateYAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
view.setY((Float) valueAnimator.getAnimatedValue());
}
});
translateYAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
animator.removeAllListeners();
finish();
overridePendingTransition(0, 0);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
translateYAnimator.setDuration(300);
translateYAnimator.start();
}
private void performEnterAnimation() {
final DragPhotoView photoView = mDragPhotoView;
ValueAnimator translateXAnimator = ValueAnimator.ofFloat(photoView.getX(), 0);
translateXAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
photoView.setX((Float) valueAnimator.getAnimatedValue());
}
});
translateXAnimator.setDuration(300);
translateXAnimator.start();
ValueAnimator translateYAnimator = ValueAnimator.ofFloat(photoView.getY(), 0);
translateYAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
photoView.setY((Float) valueAnimator.getAnimatedValue());
}
});
translateYAnimator.setDuration(300);
translateYAnimator.start();
ValueAnimator scaleYAnimator = ValueAnimator.ofFloat(mScaleY, 1);
scaleYAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
photoView.setScaleY((Float) valueAnimator.getAnimatedValue());
}
});
scaleYAnimator.setDuration(300);
scaleYAnimator.start();
ValueAnimator scaleXAnimator = ValueAnimator.ofFloat(mScaleX, 1);
scaleXAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
photoView.setScaleX((Float) valueAnimator.getAnimatedValue());
}
});
scaleXAnimator.setDuration(300);
scaleXAnimator.start();
}
private void setStatusColor() {
Bitmap b = convertViewToBitmap(mRelativeLayout);
Palette palette = Palette.generate(b);
if (palette.getLightVibrantSwatch() != null) {
getWindow().setStatusBarColor(palette.getLightVibrantSwatch().getRgb());
}
}
private Bitmap convertViewToBitmap(View view) {
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}
}