Material-Animations讲解笔记

令狐良骏
2023-12-01

写写自己的见解,也加深自己的理解。

主页中MainActivity中

//设置动画
setupWindowAnimations();
//添加数据
setupSamples();
//
setupToolbar();
setupLayout();

slide是滑动动画,setupWindowAnimations()方法中

// Re-enter transition is executed when returning to this activity
//activity页面滑动进入退出时的动画效果
Slide slideTransition = new Slide();
slideTransition.setSlideEdge(Gravity.LEFT);
slideTransition.setDuration(getResources().getInteger(R.integer.anim_duration_long));

把滑动动画加入activity中

//从上个activity返回到本activity时执行的动画
getWindow().setReenterTransition(slideTransition);
//跳转到别的activity时,退出当前activity时执行的动画
getWindow().setExitTransition(slideTransition);
同样的还有

(1)setExitTransition() - 当A start B时,使A中的View退出场景的transition

(2)setEnterTransition() - 当A start B时,使B中的View进入场景的transition

(3)setReturnTransition() - 当B 返回 A时,使B中的View退出场景的transition

(4)setReenterTransition() - 当B 返回 A时,使A中的View进入场景的transition

深入理解可以看此页面的详细讲解http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0116/2320.html


关于mainactivity中的跳转全部封装在adapter中;此adapter应用了MVVM的架构;

@Override
public SamplesViewHolder onCreateViewHolder(ViewGroup parent, int position) {
    //mvvm框架的应用
    RowSampleBinding binding = RowSampleBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
    return new SamplesViewHolder(binding.getRoot());
}

跳转的方法定义采用重载,方法名相同,参数不同

private void transitionToActivity(Class target, Sample sample) {
    final Pair<View, String>[] pairs = TransitionHelper.createSafeTransitionParticipants(activity, true);
    startActivity(target, pairs, sample);
}


private void transitionToActivity(Class target, SamplesViewHolder viewHolder, Sample sample, int transitionName) {
    final Pair<View, String>[] pairs = TransitionHelper.createSafeTransitionParticipants(activity, false,
            new Pair<>(viewHolder.binding.sampleIcon, activity.getString(transitionName)));
    startActivity(target, pairs, sample);
}

private void transitionToActivity(Class target, SamplesViewHolder viewHolder, Sample sample) {
    final Pair<View, String>[] pairs = TransitionHelper.createSafeTransitionParticipants(activity, false,
            new Pair<>(viewHolder.binding.sampleIcon, activity.getString(R.string.square_blue_name)),
            new Pair<>(viewHolder.binding.sampleName, activity.getString(R.string.sample_blue_title)));
    startActivity(target, pairs, sample);
}

private void startActivity(Class target, Pair<View, String>[] pairs, Sample sample) {
    Intent i = new Intent(activity, target);
    ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, pairs);
    i.putExtra("sample", sample);
    activity.startActivity(i, transitionActivityOptions.toBundle());
}

TransitionHelper.createSafeTransitionParticipants();此方法参数为真时顶部状态栏不参与移动;pairs封装入需要移动的view,跳转后的页面中的对应view需要添加android:transitionName=“string”属性;string要相同

activity的跳转使用ActivityOptionsCompat.makeSceneTransitionAnimation();

同类型的还有:(别处抄的)

1.平移,跟我们的overridePendingTransition效果是一样的,从第二个和第三个参数就可以看出
ActivityOptionsCompat.makeCustomAnimation(Context context, int enterResId, int exitResId)

2.将一个控件平滑的放大过渡到第二个activity,一般用于相册的具体照片的查看
ActivityOptionsCompat.makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)

3.
ActivityOptionsCompat.makeThumbnailScaleUpAnimation(View source,Bitmap thumbnail, int startX, int startY)

4.平滑的将一个控件平移的过渡到第二个activity
ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName)

5. 平滑的将多个控件平移的过渡到第二个activity
ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity,Pair<View, String>… sharedElements)</code>
想要移动主题style还需添加这句话: <item name="android:windowContentTransitions">true</item>

MainActivity完毕

TrantsitionsActivity1中:

//淡入淡出的效果
Fade enterTransition = new Fade();
enterTransition.setDuration(getResources().getInteger(R.integer.anim_duration_long));
// This view will not be affected by enter transition animation
enterTransition.excludeTarget(R.id.square_red, true);
findViewById(R.id.sample1_button5).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Visibility returnTransition = buildReturnTransition();
        getWindow().setReturnTransition(returnTransition);

        finishAfterTransition();
    }
});
findViewById(R.id.sample1_button6).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        /**
         * If no return transition is defined Android will use reversed enter transition
         * In this case, return transition will be a reversed Slide (defined in buildEnterTransition)
         */
        finishAfterTransition();
    }
});

TrantsitionsActivity2与TrantsitionsActivity3分别是explode与slide在java代码与xml文件中的不同应用。


SharedElementActivity基本与TrantsitionsActivity1相同,只是换了个写法而已,标题和中心圆之所以能移动是在xml文件中添加了android:transitionName=“string”属性

private void setupLayout(Sample sample) {
    // Transition for fragment1
    Slide slideTransition = new Slide(Gravity.LEFT);
    slideTransition.setDuration(getResources().getInteger(R.integer.anim_duration_long));
    // Create fragment and define some of it transitions
    SharedElementFragment1 sharedElementFragment1 = SharedElementFragment1.newInstance(sample);
    //同activity的一样的效果
    sharedElementFragment1.setReenterTransition(slideTransition);
    sharedElementFragment1.setExitTransition(slideTransition);
    sharedElementFragment1.setSharedElementEnterTransition(new ChangeBounds());

    getSupportFragmentManager().beginTransaction()
            .replace(R.id.sample2_content, sharedElementFragment1)
            .commit();
}

SharedElementFragment1中跳转到SharedElementFragment2的代码

private void addNextFragment(Sample sample, ImageView squareBlue, boolean overlap) {
    SharedElementFragment2 sharedElementFragment2 = SharedElementFragment2.newInstance(sample);

    Slide slideTransition = new Slide(Gravity.RIGHT);
    slideTransition.setDuration(getResources().getInteger(R.integer.anim_duration_medium));

    ChangeBounds changeBoundsTransition = new ChangeBounds();
    changeBoundsTransition.setDuration(getResources().getInteger(R.integer.anim_duration_medium));

    sharedElementFragment2.setEnterTransition(slideTransition);
    sharedElementFragment2.setAllowEnterTransitionOverlap(overlap);//为真时两个页面切换会有延迟效果,重叠在一起
    sharedElementFragment2.setAllowReturnTransitionOverlap(overlap);
    sharedElementFragment2.setSharedElementEnterTransition(changeBoundsTransition);

    getFragmentManager().beginTransaction()
            .replace(R.id.sample2_content, sharedElementFragment2)
            .addToBackStack(null)
            .addSharedElement(squareBlue, getString(R.string.square_blue_name))
            .commit();
}

SharedElementActivity完毕;

AnimationsActivity1跳转同TrantsitionsActivity1

改变父控件中view的位置与大小所加载的动画效果:

TransitionManager.beginDelayedTransition(viewRoot);

AnimationsActivity2中的四个view的切换效果是TransitionManager与scene结合transitionSet写出来的动画效果;


AnimationsActivity1完毕;

RevealActivity进入页面的动画效果:

setupEnterAnimations();中

Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.changebounds_with_arcmotion);
getWindow().setSharedElementEnterTransition(transition);
四个view的动画效果最终都会执行:

private Animator animateRevealColorFromCoordinates(ViewGroup viewRoot, @ColorRes int color, int x, int y) {
    float finalRadius = (float) Math.hypot(viewRoot.getWidth(), viewRoot.getHeight());

    Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, x, y, 0, finalRadius);
    viewRoot.setBackgroundColor(ContextCompat.getColor(this, color));
    anim.setDuration(getResources().getInteger(R.integer.anim_duration_long));
    anim.setInterpolator(new AccelerateDecelerateInterpolator());
    anim.start();
    return anim;
}

完毕;

最后附上项目地址:https://github.com/lgvalle/Material-Animations



 类似资料: