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

Kotlin Compose Button 实现长按监听并实现动画效果(完整代码)

《KotlinComposeButton实现长按监听并实现动画效果(完整代码)》想要实现长按按钮开始录音,松开发送的功能,因此为了实现这些功能就需要自己写一个Button来解决问题,下面小编给大... 目录Button 实现原理1. Surface 的作用(关键)2. InteractionSource3.

使用WPF实现窗口抖动动画效果

《使用WPF实现窗口抖动动画效果》在用户界面设计中,适当的动画反馈可以提升用户体验,尤其是在错误提示、操作失败等场景下,窗口抖动作为一种常见且直观的视觉反馈方式,常用于提醒用户注意当前状态,本文将详细... 目录前言实现思路概述核心代码实现1、 获取目标窗口2、初始化基础位置值3、创建抖动动画4、动画完成后

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整