写写自己的见解,也加深自己的理解。
主页中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时执行的动画 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()); }
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(); }
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