Android Activity 转场动画

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xingxtao/article/details/83691161

序言

好久没有写博客了,真是越来越懒了,还是要改变!今天学习了很有可能会应用到工作中的动画效果。

效果图

实现思路

LoginActivity 通过转场动画跳转到 MainActivity :

  1. 在 LoginActivity 中确定动画的开始位置坐标,并通过 intent 传递给 MainActivity。
  2. MainActivity 拿到动画起始位置执行动画,如果需要 finish 掉 LoginActivity ,在 MainActivity 动画执行结束时 finish 掉。
  3. MainActivity 的 window 背景需要设置为透明,并且 根布局 background 需要设置为非透明的。
  4. 动画执行结束销毁 LoginActivity ,采用本地广播方式。

实现代码

LoginActivity :
activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/login_bg"
    tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dp"
        android:onClick="click"
        android:text="login" />

</RelativeLayout>

LoginActivity.java

public class LoginActivity extends AppCompatActivity {

    public static final String POSITION_X = "position_x";
    public static final String POSITION_Y = "position_y";
    private BroadcastReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        registerBroadcast();
    }

    private void registerBroadcast() {
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (MainActivity.ACTION_CLOSE_LOGIN.equals(action)) {
                    finish();
                }
            }
        };
        IntentFilter filter = new IntentFilter(MainActivity.ACTION_CLOSE_LOGIN);
        LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
    }


    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void click(View view) {
        ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, view, "transtion");
        // 起始位置
        int startX = (int) (view.getX() + view.getWidth() / 2);
        int startY = (int) (view.getY() + view.getHeight() / 2);
        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra(POSITION_X, startX);
        intent.putExtra(POSITION_Y, startY);
        startActivity(intent, options.toBundle());
        // 要等 MainActivity动画执行结束才能 finish 掉
//        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (receiver != null) {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
        }
    }
}

MainActivity 布局就两张图片,布局代码省略。
MainActivity.java

public class MainActivity extends AppCompatActivity {

    public static final String ACTION_CLOSE_LOGIN = "com.xing.activityanim.CLOSE_LOGIN";

    private LinearLayout rootLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rootLayout = findViewById(R.id.rl_main_root);
        Intent intent = getIntent();
        final int startX = intent.getIntExtra(LoginActivity.POSITION_X, 0);
        final int startY = intent.getIntExtra(LoginActivity.POSITION_Y, 0);

        // 系统版本在 5.0 以上,执行转场动画
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver();
            if (viewTreeObserver.isAlive()) {
                viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        revealActivity(startX, startY);
//                        viewTreeObserver.removeOnGlobalLayoutListener(this);   // 这样写会报错
                        rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }
                });
            }
        } else {

        }
    }


    private void revealActivity(int x, int y) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            float finalRadius = Math.max(rootLayout.getWidth(), rootLayout.getHeight());
            Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, x, y, 0, finalRadius);
            circularReveal.setDuration(600);
            circularReveal.setInterpolator(new LinearInterpolator());
            circularReveal.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    // 发送关闭 LoginActivity 广播
                    sendCloseBroadcast();
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            circularReveal.start();
        }
        rootLayout.setVisibility(View.VISIBLE);


    }

    private void sendCloseBroadcast() {
        Intent intent = new Intent(ACTION_CLOSE_LOGIN);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
}

其中 MainActivity 配置了透明主题

Androidmanifest.xml

<activity
            android:name=".MainActivity"
            android:theme="@style/TransparentTheme" />

styles.xml

 <style name="TransparentTheme" parent="AppTheme">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    </style>

猜你喜欢

转载自blog.csdn.net/xingxtao/article/details/83691161