本系列文章一共5篇
谁说Android的动画不廉价(一)之项目分层
谁说Android的动画不廉价(二)之转场动画
谁说Android的动画不廉价(三)之共享元素动画
谁说Android的动画不廉价(四)之元素动画
谁说Android的动画不廉价(五)之水波纹动画
GitHub源码

引言

本篇博文是基于上一篇博文谁说Android的动画不廉价(三)之共享元素动画的基础上做的拓展。

目标效果图

转场动画

前提说明

其实这篇博文分为两个动画。

  • 第一种就是标题上的元素动画。就是View的位置,大小发生改变时伴随着动画效果。
  • 另一种就是场景动画,同一些元素,在不同layout里面的位置大小不同,然后通过切换场景来模拟View的位置大小改变。不同的layout元素可以不一样,Android根据id来判断是否为同一个元素。两个layout没有相同元素的旧layout元素将会使用退出动画,然后没有相同元素的新layout元素将会使用进入动画

元素动画

如何开启

改变View的大小,位置之前使用TransitionManager.beginDelayedTransition(ViewGroup sceneRoot, [Transition transition]);开启

  • sceneRoot : 元素所在的ViewGroup
  • transition : 改变时的动画效果

场景动画

如何加载场景

通过Scene.getSceneForLayout(ViewGroup viewGroup,int layoutID,Context context);方法加载一个场景

  • viewGroup : layout需要加入的ViewGroup,类似于Fragment使用中的FrameLayout容器
  • layoutID : 场景的布局文件资源id

如何切换

通过TransitionManager.go(Scene scene,[Transition transition]);方法来切换场景

元素动画

布局文件

activity_view_animation.xml

谁说Android的动画不廉价(四)之元素动画_第1张图片 元素动画布局
<?xml version="1.0" encoding="utf-8"?>                    

代码

MainActivity.java

 public void viewAnimations(View v) {        Intent intent = new Intent(this, ViewAnimationActivity.class);        ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this);        startActivity(intent, activityOptionsCompat.toBundle());    }

ViewAnimationActivity.java

package demo.august1996.top.transitionanimationsdemo;import android.content.Intent;import android.support.v4.app.ActivityOptionsCompat;import android.transition.TransitionManager;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import demo.august1996.top.transitionanimationsdemo.Activity.ToolbarActivity;public class ViewAnimationActivity extends ToolbarActivity {    ViewGroup container;    View imageView;    boolean isChangeSize = false;    boolean isChangePosition = false;    @Override    protected String getToolbarTitle() {        return "元素动画";    }    @Override    protected void initView() {        imageView = findViewById(R.id.img);        container = (ViewGroup) findViewById(R.id.container);    }    @Override    protected int getContentViewID() {        return R.layout.activity_view_animation;    }    @Override    protected boolean canBack() {        return true;    }    /**     * 修改指定View的大小,根据isChangeSize来判断     * isChangeSize == true:为修改过的大小,大小*2     * isChangeSize == false:为原始的大小,大小/2     * @param v     */    public void changeSize(View v) {        TransitionManager.beginDelayedTransition(container);        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams();        if (isChangeSize) {            layoutParams.width = layoutParams.width * 2;        } else {            layoutParams.width = layoutParams.width / 2;        }        layoutParams.height = layoutParams.width;        imageView.setLayoutParams(layoutParams);        isChangeSize = !isChangeSize;    }    /**     * 与changeSize类似     * @param v     */    public void changePosition(View v) {        TransitionManager.beginDelayedTransition(container);        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams();        if (isChangePosition) {            layoutParams.gravity = Gravity.CENTER;        } else {            layoutParams.gravity = Gravity.LEFT;        }        imageView.setLayoutParams(layoutParams);        imageView.postInvalidate();        isChangePosition = !isChangePosition;    }    public void next(View v) {        Intent intent = new Intent(this, SceneActivity.class);        ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this);        startActivity(intent, activityOptionsCompat.toBundle());    }}

改变View的布局参数前开启动画效果TransitionManager.beginDelayedTransition(container);

场景动画

布局文件

比较多,1个Activity的layout加上5个场景的layout
第一个是初始化的场景,其余四个是含有相同的元素,只是位置不同。

activity_scene.xml

<?xml version="1.0" encoding="utf-8"?>                                    
  • FrameLayout就是我们场景需要加载的地方
  • 而且我们看到按钮有放大且透明出现的效果,所以我们先把scaleXscaleYalpha设置成0

sences_layout_0.xml

<?xml version="1.0" encoding="utf-8"?>    

sences_layout_1.xml

<?xml version="1.0" encoding="utf-8"?>                

sences_layout_2.xml

<?xml version="1.0" encoding="utf-8"?>                

sences_layout_3.xml

<?xml version="1.0" encoding="utf-8"?>                

sences_layout_4.xml

<?xml version="1.0" encoding="utf-8"?>                

代码

SceneActivity.java

package demo.august1996.top.transitionanimationsdemo;import android.transition.ChangeBounds;import android.transition.Scene;import android.transition.Slide;import android.transition.TransitionManager;import android.transition.TransitionSet;import android.view.View;import android.view.ViewGroup;import android.view.animation.BounceInterpolator;import java.util.ArrayList;import java.util.List;import demo.august1996.top.transitionanimationsdemo.Activity.ToolbarActivity;public class SceneActivity extends ToolbarActivity {    /**     * 用于动画效果的按钮     */    List buttonList = new ArrayList<>();    /**     * 添加场景到该ViewGroup     */    ViewGroup viewRoot;    /**     * 一共5个场景,0为默认场景     */    Scene scene0;    Scene scene1;    Scene scene2;    Scene scene3;    Scene scene4;    @Override    protected void beforeInitView() {        super.beforeInitView();    }    @Override    protected String getToolbarTitle() {        return "场景动画";    }    @Override    protected void initView() {        /**         * 初始化按钮View         */        buttonList.add(findViewById(R.id.one));        buttonList.add(findViewById(R.id.two));        buttonList.add(findViewById(R.id.three));        buttonList.add(findViewById(R.id.four));        viewRoot = (ViewGroup) findViewById(R.id.viewRoot);        /**         * 初始化场景         */        scene0 = Scene.getSceneForLayout(viewRoot, R.layout.sences_layout_0, this);        scene1 = Scene.getSceneForLayout(viewRoot, R.layout.sences_layout_1, this);        scene2 = Scene.getSceneForLayout(viewRoot, R.layout.sences_layout_2, this);        scene3 = Scene.getSceneForLayout(viewRoot, R.layout.sences_layout_3, this);        scene4 = Scene.getSceneForLayout(viewRoot, R.layout.sences_layout_4, this);        /**         * 当场景1被切换的时候,按钮显示动画         */        scene0.setEnterAction(new Runnable() {            @Override            public void run() {                for (int i = 0; i < buttonList.size(); i++) {                    View view = buttonList.get(i);                    view.animate()                            .setDuration(1000)                            .scaleX(1)                            .scaleY(1)                            .alpha(1)                            .start();                }            }        });        /**         * 切换到场景0         */        TransitionManager.go(scene0);    }    /**     * 使用简单动画切换场景1     * @param v     */    public void one(View v) {        TransitionManager.go(scene1, new ChangeBounds());    }    /**     * 使用混合动画加载场景2     * @param v     */    public void two(View v) {        TransitionSet transitionSet = new TransitionSet();        transitionSet.setDuration(1000);        Slide slide = new Slide();        ChangeBounds changeBounds = new ChangeBounds();        transitionSet.addTransition(slide);        transitionSet.addTransition(changeBounds);        TransitionManager.go(scene2, transitionSet);    }    /**     * 使用混合动画加载场景3,并设置动画顺序     * @param v     */    public void three(View v) {        TransitionSet transitionSet = new TransitionSet();        transitionSet.setDuration(1000);        Slide slide = new Slide();        ChangeBounds changeBounds = new ChangeBounds();        transitionSet.addTransition(slide);        transitionSet.addTransition(changeBounds);        transitionSet.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);        TransitionManager.go(scene3, transitionSet);    }    /**     * 使用混合动画加载场景4,并设置动画顺序和差时器     * @param v     */    public void four(View v) {        TransitionSet transitionSet = new TransitionSet();        transitionSet.setDuration(1000);        transitionSet.setInterpolator(new BounceInterpolator());        Slide slide = new Slide();        ChangeBounds changeBounds = new ChangeBounds();        transitionSet.addTransition(slide);        transitionSet.addTransition(changeBounds);        transitionSet.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);        TransitionManager.go(scene4, transitionSet);    }    @Override    protected int getContentViewID() {        return R.layout.activity_scene;    }    @Override    protected boolean canBack() {        return true;    }}

我们的效果图

我们的效果图

更多相关文章

  1. 谁说Android的动画不廉价(五)之水波纹动画
  2. Android属性动画设置中心点
  3. Android多种View动画:EasyAndroidAnimations
  4. Android之gif动画实现
  5. RecyclerView 实现item点击水波纹动画
  6. android启动画面
  7. android 设置布局动画
  8. RotateAniamtion_实现Android简单动画旋转案例

随机推荐

  1. 手机游戏开发 保持屏幕常亮
  2. android中dialog封装
  3. Android小笔记之存储与读取
  4. Android 自定义ImageView,支持圆角和直角
  5. 1、android 模拟小球来回撞墙效果(游戏的
  6. android 返回键 事件
  7. android打电话、发短信实现
  8. Vibrator
  9. Android在线资源API
  10. Android Activity设置无标题和全屏