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; } }