android Activity转场动画makeSceneTransitionAnimation

本文主要是介绍android Activity转场动画makeSceneTransitionAnimation,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、activity转场动画实现有很多,这里主要记录ActivityOptions实现转场动画。

1、makeSceneTransitionAnimation实现,网上很多说要添加下面这句代码

<item name="android:windowContentTransitions">true</item>

或者Activity中添加requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);,但是实际不添加也可以

2、显示图片的那个ImageView要添加transitionName,两边显示的都要添加

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.example.mytestproject.view.ZoomImageViewandroid:id="@+id/zoomImageView"android:layout_width="match_parent"android:src="@mipmap/item"android:transitionName="zoomImage"android:layout_height="match_parent"/></RelativeLayout>
3、跳转到的那个Activity要添加下面的属性
* changeBounds - 改变目标视图的布局边界
* changeClipBounds - 裁剪目标视图边界
* changeTransform - 改变目标视图的缩放比例和旋转角度
* changeImageTransform - 改变目标图片的大小和缩放比例
TransitionSet transitionSet = new TransitionSet();transitionSet.setOrdering(TransitionSet.ORDERING_TOGETHER);transitionSet.addTransition(new ChangeBounds());transitionSet.addTransition(new ChangeTransform());transitionSet.addTransition(new ChangeClipBounds());transitionSet.addTransition(new ChangeImageTransform());transitionSet.addTarget(mZoomImageView);getWindow().setSharedElementEnterTransition(transitionSet);getWindow().setSharedElementExitTransition(transitionSet);getWindow().setSharedElementsUseOverlay(true);

4、onBackPressed返回中添加

ActivityCompat.finishAfterTransition(this);

5、跳转动画实现,makeSceneTransitionAnimation实现,这个返回的时候也会有动画效果

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(RecyclerActivity.this,imageView, "zoomImage");Intent intent = new Intent(RecyclerActivity.this, ZoomActivity.class);startActivityForResult(intent, 1, options.toBundle());
makeScaleUpAnimation实现、这个是一个放大的效果
ActivityOptions options = ActivityOptions.makeScaleUpAnimation(imageView,imageView.getWidth() / 2, imageView.getHeight() / 2, 0, 0);
Intent intent = new Intent(RecyclerActivity.this, ZoomActivity.class);startActivityForResult(intent, 1, options.toBundle());

还有下面几个动画效果,都可以看看

public static ActivityOptions makeClipRevealAnimation(View source, int startX, int startY, int width, int height)

public static ActivityOptions makeCustomAnimation(Context context, int enterResId, int exitResId)

public static ActivityOptions makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY)

startActivity(new Intent(this, ZoomActivity.class), ActivityOptions.makeSceneTransitionAnimation (this, Pair.create(view, "myButton2"), Pair.create(view, "myButton3")) .toBundle());

6、最后给一个可以实现缩放移动等操作的图片显示View,有兴趣可以看看

package com.example.mytestproject.view;import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;import androidx.appcompat.widget.AppCompatImageView;/*** 保存图片点击的缩放类* create by xing* 2020/8*/
public class ZoomImageView extends AppCompatImageView implements View.OnTouchListener, ScaleGestureDetector.OnScaleGestureListener {private final String TAG = "ZoomImageView";private Matrix mMatrix;private PointF mViewSize;private PointF mImageSize;private PointF mScaleSize;private PointF mCurPoint;private PointF mOriginScale;private ScaleGestureDetector mScaleGestureDetector = null;private GestureDetector mGestureDetector;private final float[] mMatrixValues = new float[9];private boolean isAutoScale;public static final float SCALE_MAX = 4.0f;private static final float SCALE_MID = 0.5f;private float mInitScale = 0.5f;private float mLastX;private float mLastY;private boolean isCanDrag;private int lastPointerCount;private boolean isCheckTopAndBottom = true;private boolean isCheckLeftAndRight = true;private float mDownX, mDownY = 0;private IGestureImageListener iGestureImageListener;public interface IGestureImageListener {void ZoomClick();}public void setGestureImageListener(IGestureImageListener listener) {this.iGestureImageListener = listener;}public ZoomImageView(Context context) {super(context);GestureImageViewInit(context);}public ZoomImageView(Context context, AttributeSet attrs) {super(context, attrs);GestureImageViewInit(context);}public ZoomImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);GestureImageViewInit(context);}public void GestureImageViewInit(Context context) {this.setOnTouchListener(this);this.setScaleType(ScaleType.MATRIX);mMatrix = new Matrix();mOriginScale = new PointF();mScaleSize = new PointF();mCurPoint = new PointF();mGestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener() {@Overridepublic boolean onDoubleTap(MotionEvent e) {if (isAutoScale == true)return true;float x = e.getX();float y = e.getY();if (getScale() < SCALE_MID) {ZoomImageView.this.postDelayed(new ZoomImageView.AutoScaleRunnable(SCALE_MID, x, y), 16);isAutoScale = true;} else if (getScale() >= SCALE_MID && getScale() < SCALE_MAX) {ZoomImageView.this.postDelayed(new ZoomImageView.AutoScaleRunnable(SCALE_MAX, x, y), 16);isAutoScale = true;} else {ZoomImageView.this.postDelayed(new ZoomImageView.AutoScaleRunnable(mInitScale, x, y), 16);isAutoScale = true;}return true;}});mScaleGestureDetector = new ScaleGestureDetector(context, this);this.setOnTouchListener(this);}private class AutoScaleRunnable implements Runnable {static final float BIGGER = 1.07f;static final float SMALLER = 0.43f;private float mTargetScale;private float tmpScale;private float x;private float y;public AutoScaleRunnable(float targetScale, float x, float y) {this.mTargetScale = targetScale;this.x = x;this.y = y;if (getScale() < mTargetScale) {tmpScale = SMALLER;} else {tmpScale = SMALLER;}}@Overridepublic void run() {// 进行缩放mMatrix.postScale(tmpScale, tmpScale, x, y);checkBorderAndCenterWhenScale();setImageMatrix(mMatrix);final float currentScale = getScale();if (((tmpScale > 1f) && (currentScale < mTargetScale))|| ((tmpScale < 1f) && (mTargetScale < currentScale))) {ZoomImageView.this.postDelayed(this, 16);} else {final float deltaScale = mTargetScale / currentScale;mMatrix.postScale(deltaScale, deltaScale, x, y);checkBorderAndCenterWhenScale();setImageMatrix(mMatrix);isAutoScale = false;}}}@Overridepublic boolean onScale(ScaleGestureDetector detector) {float scale = getScale();float scaleFactor = detector.getScaleFactor();if (getDrawable() == null)return true;if ((scale < SCALE_MAX && scaleFactor > 1.0f)|| (scale > mInitScale && scaleFactor < 1.0f)) {if (scaleFactor * scale < mInitScale) {scaleFactor = mInitScale / scale;}if (scaleFactor * scale > SCALE_MAX) {scaleFactor = SCALE_MAX / scale;}mMatrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());checkBorderAndCenterWhenScale();setImageMatrix(mMatrix);}return true;}private RectF getMatrixRectF() {Matrix matrix1 = mMatrix;RectF rect = new RectF();Drawable d = getDrawable();if (null != d) {rect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());matrix1.mapRect(rect);}return rect;}private void checkBorderAndCenterWhenScale() {RectF rect = getMatrixRectF();float deltaX = 0;float deltaY = 0;int width = getWidth();int height = getHeight();// 如果宽或高大于屏幕,则控制范围if (rect.width() >= width) {if (rect.left > 0) {deltaX = -rect.left;}if (rect.right < width) {deltaX = width - rect.right;}}if (rect.height() >= height) {if (rect.top > 0) {deltaY = -rect.top;}if (rect.bottom < height) {deltaY = height - rect.bottom;}}if (rect.width() < width) {deltaX = width * 0.5f - rect.right + 0.5f * rect.width();}if (rect.height() < height) {deltaY = height * 0.5f - rect.bottom + 0.5f * rect.height();}mMatrix.postTranslate(deltaX, deltaY);}@Overridepublic boolean onScaleBegin(ScaleGestureDetector detector) {return true;}@Overridepublic void onScaleEnd(ScaleGestureDetector detector) {}public final float getScale() {mMatrix.getValues(mMatrixValues);return mMatrixValues[Matrix.MSCALE_X];}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);mViewSize = new PointF(width, height);Drawable drawable = getDrawable();if (drawable == null) {Log.e(TAG, "drawable is nullPtr");} else {mImageSize = new PointF(drawable.getMinimumWidth(), drawable.getMinimumHeight());}fitCenter();}/*** 使图片保存在中央*/public void fitCenter() {if (mViewSize != null && mImageSize != null) {float scaleH = mViewSize.y / mImageSize.y;float scaleW = mViewSize.x / mImageSize.x;float scale = scaleH < scaleW ? scaleH : scaleW;//根据view适应大小setImageScale(new PointF(scale, scale));mOriginScale.set(scale, scale);//根据缩放因子大小来将图片中心调整到view 中心if (scaleH < scaleW) {setImageTranslation(new PointF(mViewSize.x / 2 - mScaleSize.x / 2, 0));} else {setImageTranslation(new PointF(0, mViewSize.y / 2 - mScaleSize.y / 2));}//记录缩放因子 下次继续从这个比例缩放mInitScale = mOriginScale.x;}}@Overridepublic boolean onTouch(View v, MotionEvent event) {if (mGestureDetector.onTouchEvent(event))return true;mScaleGestureDetector.onTouchEvent(event);float x = 0, y = 0;final int pointerCount = event.getPointerCount();for (int i = 0; i < pointerCount; i++) {x += event.getX(i);y += event.getY(i);}x = x / pointerCount;y = y / pointerCount;if (pointerCount != lastPointerCount) {isCanDrag = false;mLastX = x;mLastY = y;}lastPointerCount = pointerCount;RectF rectF = getMatrixRectF();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (rectF.width() > getWidth() || rectF.height() > getHeight()) {getParent().requestDisallowInterceptTouchEvent(true);}mDownX = event.getX();mDownY = event.getY();break;case MotionEvent.ACTION_MOVE:if (rectF.width() > getWidth() || rectF.height() > getHeight()) {getParent().requestDisallowInterceptTouchEvent(true);}float dx = x - mLastX;float dy = y - mLastY;if (!isCanDrag) {isCanDrag = isCanDrag(dx, dy);}if (isCanDrag) {if (getDrawable() != null) {isCheckLeftAndRight = isCheckTopAndBottom = true;if (rectF.width() < getWidth()) {dx = 0;isCheckLeftAndRight = false;}if (rectF.height() < getHeight()) {dy = 0;isCheckTopAndBottom = false;}mMatrix.postTranslate(dx, dy);checkMatrixBounds();setImageMatrix(mMatrix);}}mLastX = x;mLastY = y;break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:float diffX = Math.abs(event.getX() - mDownX);float diffY = Math.abs(event.getY() - mDownY);if (diffX < 5 && diffY < 5) {if (iGestureImageListener != null) {iGestureImageListener.ZoomClick();}}lastPointerCount = 0;break;}return true;}private void checkMatrixBounds() {RectF rect = getMatrixRectF();float deltaX = 0, deltaY = 0;final float viewWidth = getWidth();final float viewHeight = getHeight();// 判断移动或缩放后,图片显示是否超出屏幕边界if (rect.top > 0 && isCheckTopAndBottom) {deltaY = -rect.top;}if (rect.bottom < viewHeight && isCheckTopAndBottom) {deltaY = viewHeight - rect.bottom;}if (rect.left > 0 && isCheckLeftAndRight) {deltaX = -rect.left;}if (rect.right < viewWidth && isCheckLeftAndRight) {deltaX = viewWidth - rect.right;}mMatrix.postTranslate(deltaX, deltaY);}/*** 根据缩放因子缩放图片** @param scale*/public void setImageScale(PointF scale) {mMatrix.setScale(scale.x, scale.y);mScaleSize.set(scale.x * mImageSize.x, scale.y * mImageSize.y);this.setImageMatrix(mMatrix);}/*** 根据偏移量改变图片位置** @param offset*/public void setImageTranslation(PointF offset) {mMatrix.postTranslate(offset.x, offset.y);mCurPoint.set(offset);this.setImageMatrix(mMatrix);}private boolean isCanDrag(float dx, float dy) {return Math.sqrt((dx * dx) + (dy * dy)) >= 0;}
}

 

这篇关于android Activity转场动画makeSceneTransitionAnimation的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1031172

相关文章

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

在Android中使用WebView在线查看PDF文件的方法示例

《在Android中使用WebView在线查看PDF文件的方法示例》在Android应用开发中,有时我们需要在客户端展示PDF文件,以便用户可以阅读或交互,:本文主要介绍在Android中使用We... 目录简介:1. WebView组件介绍2. 在androidManifest.XML中添加Interne

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio