Android 基于控件位置的缩放转场动画

时间:2021-02-09 10:45:57
    public static void startWithFragment(Context context, String fragmentName, Bundle args,
Fragment resultTo, int resultRequestCode, String titleResPackageName, int titleResId,
CharSequence title, boolean isShortcut) {
Intent intent = onBuildStartFragmentIntent(context, fragmentName, args, titleResPackageName,
titleResId, title, isShortcut);
android.util.Log.e("SHUIYES","mOptsBundle: "+mOptsBundle);
if (resultTo == null) {
if(mOptsBundle != null) {
context.startActivity(intent,mOptsBundle);
mOptsBundle = null;
}else{
context.startActivity(intent);
}
} else {
resultTo.startActivityForResult(intent, resultRequestCode);
}
}

private static Bundle mOptsBundle = null;
private static float[] mAnimationBounds = new float[4];
public static void setSubSettingsOpenEnterAnimation(View v){
int left = 0, top = 0;
int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
int[] location = new int[2];
v.getLocationOnScreen(location);
mAnimationBounds[0] = location[0];
mAnimationBounds[1] = location[1];
mAnimationBounds[2] = width;
mAnimationBounds[3] = height;
// or makeClipRevealAnimation (system api)
ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, left, top, width, height);
mOptsBundle = opts != null ? opts.toBundle() : null;
}

// cp form Apptransition.java
private static float computePivot(float startPos, float finalScale) {
final float denom = finalScale-1f;
if (Math.abs(denom) < .0001f) {
return startPos;
}
return -startPos / denom;
}

public static AnimationSet getSubSettingsCloseExitAnimation(float screenW, float screenH){
float startX = mAnimationBounds[0];
float startY = mAnimationBounds[1];
float startW = mAnimationBounds[2];
float startH = mAnimationBounds[3];

float scaleW = startW / screenW;
float scaleH = startH / screenH;
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
computePivot(startX,scaleW), computePivot(startY,scaleH));
scale.setRepeatCount(0);
scale.setFillAfter(true);
scale.setDuration(500);

Animation alpha = new AlphaAnimation(1, 0);
alpha.setRepeatCount(0);
alpha.setFillAfter(true);
alpha.setDuration(500);

AnimationSet set = new AnimationSet(false);
set.addAnimation(scale);
set.addAnimation(alpha);
return set;
}


/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.android.settings;

import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.Animation.AnimationListener;

/**
* Stub class for showing sub-settings; we can't use the main Settings class
* since for our app it is a special singleTask class.
*/
public class SubSettings extends SettingsActivity {

@Override
public boolean onNavigateUp() {
finish();
return true;
}

@Override
protected boolean isValidFragment(String fragmentName) {
Log.d("SubSettings", "Launching fragment " + fragmentName);
return true;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK){
finishWithAnimation();
return true;
}
return super.onKeyDown(keyCode, event);
}

public void finishWithAnimation(){
final View root = this.findViewById(R.id.first_layer);
if(root == null){
finish();
return;
}
Display display = this.getWindowManager().getDefaultDisplay();
final AnimationSet set = Utils.getSubSettingsCloseExitAnimation(display.getWidth(),display.getHeight());
set.setAnimationListener(new AnimationListener() {

@Override
public void onAnimationStart(Animation animation) {
//ignore
}

@Override
public void onAnimationRepeat(Animation animation) {
//ignore
}

@Override
public void onAnimationEnd(Animation animation) {
finish();
}
});

root.clearAnimation();
root.setAnimation(set);
set.startNow();
}

@Override
public void finish() {
super.finish();
// disable Activity default animation
overridePendingTransition(0, 0);
}
}


其中要对Subettings设置透明Style,

        <item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowIsTranslucent">true</item>

还有就是如果系统主题是 @android:style/Theme.Material , 则要对 Subettings 设置 Theme.Translucent ,不然上面设置无效

<activity android:name=".SubSettings"
android:theme="@android:style/Theme.Translucent.NoTitleBar"