Android 移動小球+CircularReveal頁面切換揭露動畫

效果圖如下

ScreenGif.gif

是在fragment中跳轉activity實現的效果,fragment跳fragment,activity跳activity類似~~

實現過程

  • 重寫FloatingActionButtononTouchListener()方法,使小球可以移動,并判斷邊界
  • 點擊fab時記錄坐標傳到下一個頁面,在下一個頁面展示動畫。
  • 點擊后退或者重寫onBackPressed()方法,執行動畫

重寫Fab的onTouchListener()

        floatingActionButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent ev) {
                switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        downX = ev.getX();
                        downY = ev.getY();
                        isClick = true;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        isClick = false;
                        moveX = ev.getX();
                        moveY = ev.getY();

                        int offsetX = (int) (moveX - downX);
                        int offsetY = (int) (moveY - downY);

                        //這里使用了setTranslation來移動view。。。嘗試過layout。不知道為什么fragment切換回來的時候會恢復原位
                        floatingActionButton.setTranslationX(floatingActionButton.getTranslationX() + offsetX);
                        floatingActionButton.setTranslationY(floatingActionButton.getTranslationY() + offsetY);

                        break;
                    case MotionEvent.ACTION_UP:
                        //用來觸發點擊事件
                        if (isClick) {
                            startAct();
                            return false;
                        }
                        //用來判斷移動邊界

                        if (floatingActionButton.getX() < 0) {
                            floatingActionButton.setX(0);
                        }
                        if (floatingActionButton.getX() + floatingActionButton.getWidth() > ScreenUtil.getScreenWidth(getContext())) {
                            floatingActionButton.setX(ScreenUtil.getScreenWidth(getContext()) - floatingActionButton.getWidth());
                        }
                        if (floatingActionButton.getY() < titleHeight) {
                            floatingActionButton.setY(0);
                        }
                        if (floatingActionButton.getY() + floatingActionButton.getHeight() + titleHeight >
                                getActivity().findViewById(R.id.activity_main_mainLl).getHeight() - getActivity().findViewById(R.id.fc_rg).getHeight()) {
                            floatingActionButton.setY(getBottomY());
                        }

                        break;
                }
                return true;
            }

            private void startAct() {
                //跳轉Activity,傳遞動畫參數
                Intent intent = new Intent(getActivity(), CheckWorkActivity.class);
                intent.putExtra("x", (int) floatingActionButton.getX() + floatingActionButton.getWidth() / 2);
                intent.putExtra("y", (int) floatingActionButton.getY() + floatingActionButton.getHeight() / 2);
                intent.putExtra("start_radius", floatingActionButton.getWidth() / 2);
                intent.putExtra("end_radius", DialogFragment.this.view.getHeight());
                startActivity(intent);
            }
        });

在下一個頁面中實現CircleRevel動畫

onCrete中調用

    private void initAnimation() {
        //ll為根布局
        final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll);
        linearLayout.post(new Runnable() {
            @Override
            public void run() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    Animator animator = ViewAnimationUtils.createCircularReveal(
                            linearLayout,// 操作的視圖
                            getIntent().getIntExtra("x", 0),  // 動畫的中心點X
                            getIntent().getIntExtra("y", 0) + findViewById(R.id.title).getHeight(), // 動畫的中心點Y
                            getIntent().getIntExtra("start_radius", 0),    // 動畫半徑
                            getIntent().getIntExtra("end_radius", 0)           // 動畫結束半徑
                    );
                    animator.setInterpolator(new AccelerateInterpolator());
                    animator.setDuration(500);
                    animator.start();
                }
            }
        });
    }

點擊后退或者觸發onBackPressed時候調用

    private void endAnim() {
        final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Animator animator = ViewAnimationUtils.createCircularReveal(
                    linearLayout,// 操作的視圖
                    getIntent().getIntExtra("x", 0),
                    getIntent().getIntExtra("y", 0) + findViewById(R.id.title).getHeight(),
                    getIntent().getIntExtra("end_radius", 0),
                    getIntent().getIntExtra("start_radius", 0)

            );
            animator.setInterpolator(new AccelerateInterpolator());
            animator.setDuration(500);
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    finish();
                }
            });
            animator.start();
        }
    }

還有一個重要的地方是修改兩個activity的theme

    <style name="AppThemeCircleRevel" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/blue</item>

        <item name="android:windowAnimationStyle">@null</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
    </style>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1: 獲取控件寬高 控件View有getHeight()和getwidth()方法可以獲取寬高,但是如果直接在on...
    自由人是工程師閱讀 1,834評論 0 0
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,523評論 0 17
  • 屬性動畫實際上是一種不斷地對值進行操作的機制,并將值賦值到指定對象的指定屬性上,可以是任意對象的任意屬性。屬性動畫...
    A_Coder閱讀 374評論 0 0
  • 最近的感悟很多,很值得記錄下來,也許這會讓我永遠受益。 工作這么多年,自以為積累了很多工作所需的技術,一些專業的知...
    美夢一場閱讀 253評論 0 0
  • 我鄭重承諾文章為原創,且從未在其他平臺發表。 工作三年,有時候會很苦惱,發現畢業初期那種“天高任我飛”的理想和激情...
    未雨欲語閱讀 821評論 9 7