手摸手教你用 Scene 实现炫酷的注册登录动画

Android · jeasonwong · 于 发布 · 最后由 roxas回复 · 1429 次阅读
1405

title: 手摸手教你用Scene实现炫酷的注册登录动画
date: 2016-08-20 13:48:08

tags:

项目地址:https://github.com/JeasonWong/SignUpTransition

老规矩,先上效果。

效果

先说下实现细节

  • 『SIGN UP』字符的位移
  • 圆圈扩散动画
  • 注册->登录的动画
  • 背景上升顶部图标渐变

此处插一下嘴~ 动画效果我是在materialup上看到的,实现后在设计师的效果后留言说我实现了他的效果,然后他也回应了下,我相信这样的结果也会是设计师和程序员感到最欣慰的结果。

chat

整个过度动画只要实现这些就好了,然后再说下我使用到的技术

  • 字符唯一、背景上升使用Scene
  • 登录动画使用属性动画
  • 圆圈扩散使用的ViewAnimationUtils

登录动画就是一个简单的Loading效果,在这篇文章中不是重点,我不会赘述,如果想学习,可以看我之前写的两篇手摸手来学习做Loading动画。

好的,手摸手开始了。

创建三个Scene,对应着:

  • 注册静态页面
        ...

        <RelativeLayout
            android:id="@+id/rlt_bg"
            android:layout_width="150dp"
            android:layout_height="@dimen/bar_height"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="40dp"
            android:background="@color/colorBg">

            <me.wangyuwei.signuptransition.LoginLoadingView
                android:id="@+id/login_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_centerInParent="true" />


        </RelativeLayout>
  • 登录页面
    <RelativeLayout
        android:id="@+id/rlt_bg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorBg">

        <me.wangyuwei.signuptransition.LoginLoadingView
            android:id="@+id/login_view"
            android:layout_width="150dp"
            android:layout_height="@dimen/bar_height"
            android:layout_centerInParent="true" />

    </RelativeLayout>
  • 主页面
    <RelativeLayout
        android:id="@+id/rlt_bg"
        android:layout_width="match_parent"
        android:layout_height="@dimen/bar_height"
        android:background="@color/colorBg">

        ...

    </RelativeLayout>

三个Scene中RelativeLayout的id取为一样,这样在之后操作Transition时才会有效果,这里很容易理解。

在ManActivity中有个用来展示各个Scene的ViewGroup,我这里用的FramLayout。

    <FrameLayout
        android:id="@+id/frt_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

那么在xml中该干的事我们都干完了,再回顾一下,分别是创建Scenes,创建展示Scene的ViewGroup。

显然接下来就是逻辑控制各个Scene的转换了。

MainActivity中初始化三个Scene:

    ...
    private Scene mSceneSignUp;
    private Scene mSceneLogging;
    private Scene mSceneMain;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mFrtContent = (FrameLayout) findViewById(R.id.frt_content);

        mSceneSignUp = Scene.getSceneForLayout(mFrtContent, R.layout.scene_sign_up, this);
        mSceneSignUp.setEnterAction(new Runnable() {
            @Override
            public void run() {
                final LoginLoadingView loginView = (LoginLoadingView) mFrtContent.findViewById(R.id.login_view);
                //计算LiginView的宽高
                ViewTreeObserver vto = loginView.getViewTreeObserver();
                vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        setSize(loginView.getMeasuredWidth(), loginView.getMeasuredHeight());
                    }
                });
                //绑定点击事件
                loginView.setOnClickListener(MainActivity.this);
            }
        });


        mSceneLogging = Scene.getSceneForLayout(mFrtContent, R.layout.scene_logging, this);
        mSceneLogging.setEnterAction(new Runnable() {
            @Override
            public void run() {
                final LoginLoadingView loginView = (LoginLoadingView) mFrtContent.findViewById(R.id.login_view);
                //省略控制LoginView的状态代码
                ...
                loginView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        TransitionManager.go(mSceneMain, new ChangeBounds().setDuration(mDuration).setInterpolator(new DecelerateInterpolator()));
                    }
                }, 6000);
            }
        });

        mSceneMain = Scene.getSceneForLayout(mFrtContent, R.layout.scene_main, this);
        mSceneMain.setEnterAction(new Runnable() {
            @Override
            public void run() {
                final ImageView imgMenu = (ImageView) mFrtContent.findViewById(R.id.img_menu);
                final ImageView imgUser = (ImageView) mFrtContent.findViewById(R.id.img_user);
                //属性动画完成顶部图标的渐变
                ValueAnimator animator = ValueAnimator.ofInt(0, 255);
                animator.setDuration(mDuration);
                animator.setInterpolator(new LinearInterpolator());
                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        int alpha = (int) animation.getAnimatedValue();
                        imgMenu.setImageAlpha(alpha);
                        imgUser.setImageAlpha(alpha);
                    }
                });
                animator.start();

                //展示RecyclerView
                final RecyclerView recyclerView = (RecyclerView) mFrtContent.findViewById(R.id.rv_common);
                CommonAdapter adapter = new CommonAdapter(MainActivity.this);
                recyclerView.setLayoutManager(new GridLayoutManager(MainActivity.this, 3));
                recyclerView.setAdapter(adapter);
            }
        });

        //进入Activity后默认展示场景mSceneSignUp
        TransitionManager.go(mSceneSignUp);
    }

重点

  • 使用Scene.getSceneForLayout创建Scene
  • 使用TransitionManager.go()来控制Scene之间的转换
  • 过渡Transition直接使用的ChangeBounds
  • 使用Scene.setEnterAction()来做一些进入Scene时的操作
  • 属性动画哪里都有需求 = =

以上就是Scene过渡的关键。

关于Scene的补充学习,可以看下Google放出来的官方demo,他还实现了一个自定义的Transition,android-CustomTransition

打造一个这样炫酷的效果其实并不难,我也是现学现用,只要把已知知识点进行组合,一定能发挥大能量。

共收到 2 条回复
30
d_clock · #1 ·

Perfect!巴神就是这么6!入选周一的Diycode每日精选!

1430
roxas · #2 ·

赞,向你学习。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册