Android-转场动画
本文最后更新于 794 天前,其中的信息可能已经有所发展或是发生改变。

1. OverridePendingTransition

Activity过场动画,支持有限

2. ActivityOptions

可实现①效果
Flutter的hero动画 (ShareElement)

ActivityOptionsCompat.makeCustomAnimation()
ActivityOptionsCompat.makeClipRevealAnimation()
ActivityOptionsCompat.makeScaleUpAnimation()
// 下面的相关实现可以用在这里-Activity过渡恭喜某些元素或者单独View变换使用(TransitionManager)
ActivityOptionsCompat.makeSceneTransitionAnimation()
ActivityOptionsCompat.makeSceneTransitionAnimation()
ActivityOptionsCompat.makeThumbnailScaleUpAnimation()

扩展继承Transition 示例

2.1 页面跳转
  • 打开开关 默认开启
    > requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);
  • 除了共享元素外转场
    >Window.setEnterTransition()
    Window.setExitTransition()
    Window.setSharedElementEnterTransition()
    Window.setSharedElementExitTransition()
  • 共享元素转场
    > 和Flutter Hero动画一样 需要相同的transitionName

ActivityA

private void gotoDetailActivity(Contacts contacts, final View avatarImg, final View nameTxt) {
    Intent intent = new Intent(ContactActivity.this,DetailActivity.class);
    Pair<View,String> pair1 = new Pair<>((View)avatarImg,ViewCompat.getTransitionName(avatarImg));
    Pair<View,String> pair2 = new Pair<>((View)nameTxt,ViewCompat.getTransitionName(nameTxt));
    /**
     *4、生成带有共享元素的Bundle,这样系统才会知道这几个元素需要做动画
     */
    ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(ContactActivity.this, pair1, pair2);
    ActivityCompat.startActivity(ContactActivity.this,intent,activityOptionsCompat.toBundle());
}

ActivityB

/**
 * 3、设置ShareElementTransition,指定的ShareElement会执行这个Transiton动画
 */
// 更多的transition转场动画 参考下面 自定义Transition
TransitionSet transitionSet = new TransitionSet();
transitionSet.addTransition(new ChangeBounds());
transitionSet.addTransition(new ChangeTransform());
transitionSet.addTarget(avatarImg);
transitionSet.addTarget(nameTxt);
getWindow().setSharedElementEnterTransition(transitionSet);
getWindow().setSharedElementExitTransition(transitionSet);

2.2 默认实现
  • 默认实现:Fade,Slide,Explode
  • ChangeBounds 当 View 的位置或者大小发生变化时触发对应的转场效果
ChangeBounds transition = new ChangeBounds();
transition.setInterpolator(new AnticipateInterpolator());
TransitionManager.beginDelayedTransition(mRoot, transition);
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) view3.getLayoutParams();
if (layoutParams.leftMargin == 400) {
    layoutParams.leftMargin = 50;
} else {
    layoutParams.leftMargin = 400;
}
view3.setLayoutParams(layoutParams);
  • ChangeClipBounds 当调用 view.setClipBounds() 时
ChangeClipBounds transition = new ChangeClipBounds();
transition.setInterpolator(new BounceInterpolator());
TransitionManager.beginDelayedTransition(mRoot, transition);
int width = view2.getWidth();
int height = view2.getHeight();
int gap = 140;
Rect rect = new Rect(0, gap, width, height - gap);
if (rect.equals(view2.getClipBounds())) {
    view2.setClipBounds(null);
} else {
    view2.setClipBounds(rect);
}
  • ChangeScroll 当调用 view.scrollTo()
ChangeScroll transition = new ChangeScroll();
transition.setInterpolator(new AnticipateOvershootInterpolator());
TransitionManager.beginDelayedTransition(mRoot, transition);
if (view1.getScrollX() == -100 && view1.getScrollY() == -100) {
    view1.scrollTo(0, 0);
} else {
    view1.scrollTo(-100, -100);
}
  • ChangeTransform View 的 translation、scale 和 rotation 发生改变时
ChangeTransform transition = new ChangeTransform();
transition.setInterpolator(new OvershootInterpolator());
TransitionManager.beginDelayedTransition(mRoot, transition);
if (view1.getTranslationX() == 100 && view1.getTranslationY() == 100) {
    view1.setTranslationX(0);
    view1.setTranslationY(0);
} else {
    view1.setTranslationX(100);
    view1.setTranslationY(100);
}
if (view2.getRotationX() == 30f) {
    view2.setRotationX(0);
} else {
    view2.setRotationX(30);
}
if (view3.getRotationY() == 30f) {
    view3.setRotationY(0);
} else {
    view3.setRotationY(30);
}
if (view4.getScaleX() == 0.5f && view4.getScaleY() == 0.5f) {
    view4.setScaleX(1f);
    view4.setScaleY(1f);
} else {
    view4.setScaleX(0.5f);
    view4.setScaleY(0.5f);
}
2.3 自定义Transition
  • 继承Transition,并实现下述三个方法
  • captureStartValues,captureEndValues存入动画值
  • createAnimator内取出值进行相关动画

示例自定义

private static String PROPNAME_TEXT = "xiaweizi:changeText:text";
private static String PROPNAME_TEXT_COLOR = "xiaweizi:changeTextColor:color";
private static String PROPNAME_TEXT_SIZE = "xiaweizi:changeTextSize:size";
private static String PROPNAME_TEXT_LEVEL = "xiaweizi:changeTextTypeface:level";

// 记录下起始状态属性值
private void captureValues(TransitionValues transitionValues) {
    if (transitionValues == null || !(transitionValues.view instanceof TextView)) return;
    TextView view = (TextView) transitionValues.view;
    transitionValues.values.put(PROPNAME_TEXT, view.getText());
    transitionValues.values.put(PROPNAME_TEXT_COLOR, view.getCurrentTextColor());
    transitionValues.values.put(PROPNAME_TEXT_SIZE, view.getTextSize());
    transitionValues.values.put(PROPNAME_TEXT_LEVEL, view.getTag(R.id.type_face_level));
}

@Override
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, final TransitionValues endValues) {
    if (startValues == null || endValues == null) {
        return null;
    }
    if (!(endValues.view instanceof TextView)) {
        return super.createAnimator(sceneRoot, startValues, endValues);
    }
    TextView endView = (TextView) endValues.view;
    int startTextColor = (int) startValues.values.get(PROPNAME_TEXT_COLOR);
    int endTextColor = (int) endValues.values.get(PROPNAME_TEXT_COLOR);
    ObjectAnimator animator = ObjectAnimator.ofArgb(endView, new TextColorProperty(), startTextColor, endTextColor);
    animator.setDuration(300);
    return animator;
}
2.4 Scene

页面切换 ActivityOptionsCompat.makeSceneTransitionAnimation()
页面内 View变换
– 创建前后变换的layout 注意对应前后变换View需要相同的id

详情

3. MotionLayout

详情

public class TransitionView extends View {
    private float mRatio = 1f;
    private Paint mTextPaint;
    private int mStartColor;
    private int mEndColor;
    private Rect mRect;

    public TransitionView(Context context) {
        this(context, null);
    }

    public TransitionView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TransitionView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView(context, attrs, defStyle);
    }

    private void initView(Context context, AttributeSet attrs, int defStyle) {
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.text_size));
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mStartColor = Color.WHITE;
        mEndColor = TransitionUtils.getColor(0);
        mRect = new Rect();
    }

    public void setRatio(float ratio) {
        this.mRatio = ratio;
        invalidate();
    }

    public float getRatio() {
        return mRatio;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制左边
        canvas.save();
        mRect.set(0, 0, (int) (getWidth() * mRatio), getHeight());
        canvas.clipRect(mRect);
        mTextPaint.setColor(mStartColor);
        TransitionUtils.drawTextCenter(canvas, "文本三", getWidth() / 2, getHeight() / 2, mTextPaint);
        canvas.restore();

        // 绘制右边
        canvas.save();
        mRect.set((int) (getWidth() * mRatio), 0, getWidth(), getHeight());
        canvas.clipRect(mRect);
        mTextPaint.setColor(mEndColor);
        TransitionUtils.drawTextCenter(canvas, "三本文", getWidth() / 2, getHeight() / 2, mTextPaint);
        canvas.restore();
    }
}
本文链接:https://iichen.cn/?p=580
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇