Activity 切換動畫(小米圖庫列表進入詳情頁,圖片從固定位置放大進入,縮小退出),

來源:互聯網
上載者:User

Activity 切換動畫(小米圖庫列表進入詳情頁,圖片從固定位置放大進入,縮小退出),

直接上


ok,來分析下如何?的吧

分析原理

首先確定,這是兩個不同的 Activity,從圖片列表頁跳入到圖片詳情頁;先來看進入詳情頁時的動畫,從列表中所在 item 的位置一直放大到詳情頁的顯示位置,這裡我可以先告訴大家,當我們點擊了這個 item 的時候,就已經啟動了詳情頁,然後在詳情頁做相應的動畫效果。既然是在詳情頁做動畫效果,就需要在列表頁把相應的值傳過去,列表頁 item 在螢幕上的位置,item 的大小,當然還有圖片的資源,然後在詳情頁計算動畫執行的參數。分析了進入動畫,那麼退出 Activity 的動畫就好實現了,跟進入動畫相反,但是也是要確定什麼時候執行退齣動畫,這裡退齣動畫也是放在詳情頁面實現的,當按下返回按鈕時,開始執行退齣動畫,在動畫執行完之後,把詳情頁的 Activity 結束掉;大家會問了,可以把動畫放在列表頁執行嗎?大家仔細想一下就知道,如果是進入動畫,肯定是不能的,因為詳情頁沒有啟動,有些參數無法知道,比如放大到多大,放大以後的位置是哪裡等,但是退齣動畫是可以的,但比較麻煩,需要把詳情頁的參數返回給列表頁,如果有興趣可以試著做一下。

效果實現

1、傳入詳情頁的參數擷取

            @Override            public void onItemClick(View view) {                int location[] = new int[2] ;                view.getLocationOnScreen(location);                int resId = (int) view.getTag();                Bundle bundle = new Bundle() ;                bundle.putInt("locationX",location[0]);                bundle.putInt("locationY",location[1]);                bundle.putInt("width",view.getWidth());                bundle.putInt("height",view.getHeight());                bundle.putInt("resId",resId);                Intent intent = new Intent() ;                intent.putExtras(bundle);                intent.setClass(getActivity(),PicDetailActivity.class) ;                getActivity().startActivity(intent);                getActivity().overridePendingTransition(0, 0);                Log.v("zgy","========view========"+view.getWidth()) ;            }

item 在螢幕中的座標,可以通過

int location[] = new int[2] ;view.getLocationOnScreen(location);

來擷取,記得把 Activity 的切換動畫去掉

getActivity().overridePendingTransition(0, 0);

2、進入動畫參數的 擷取

擷取列表頁傳入的值

        final int left = getIntent().getIntExtra("locationX", 0);        final int top = getIntent().getIntExtra("locationY", 0);        final int width = getIntent().getIntExtra("width", 0);        final int height = getIntent().getIntExtra("height", 0);        int resId = getIntent().getIntExtra("resId", 0);

計算動畫執行的參數

        mImageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {            @Override            public boolean onPreDraw() {                mImageView.getViewTreeObserver().removeOnPreDrawListener(this);                int location[] = new int[2];                mImageView.getLocationOnScreen(location);                mLeft = left - location[0];                mTop = top - location[1];                mScaleX = width*1.0f / mImageView.getWidth();                mScaleY = height*1.0f / mImageView.getHeight();                Log.v("zgy", "========resId========" + mImageView.getWidth()) ;                Log.v("zgy", "========resId========" + mScaleY) ;                activityEnterAnim();                return true;            }        });

因為是在 OnCreate方法中執行的,不能直接擷取的 View 的大小,因為這時 View 尚未測量完成,需要功過監聽 View 的繪製來擷取,這裡計算當前 顯示的 View 距離列表 View 的距離及放縮比例;

3、設定動畫開始執行的位置

        mImageView.setPivotX(0);        mImageView.setPivotY(0);        mImageView.setScaleX(mScaleX);        mImageView.setScaleY(mScaleY);        mImageView.setTranslationX(mLeft);        mImageView.setTranslationY(mTop);

4、開始執行進入動畫
這個時候已經啟動了 詳情頁面,所以執行動畫以後不需要做任何操作了

        mImageView.animate().scaleX(1).scaleY(1).translationX(0).translationY(0).                setDuration(1000).setInterpolator(new DecelerateInterpolator()).start();        ObjectAnimator objectAnimator = ObjectAnimator.ofInt(mBackground,"alpha",0,255);        objectAnimator.setInterpolator(new DecelerateInterpolator());        objectAnimator.setDuration(1000);        objectAnimator.start();

來看看這時候的

5、退齣動畫

        mImageView.setPivotX(0);        mImageView.setPivotY(0);        mImageView.animate().scaleX(mScaleX).scaleY(mScaleY).translationX(mLeft).translationY(mTop).                withEndAction(runnable).                setDuration(1000).setInterpolator(new DecelerateInterpolator()).start();        ObjectAnimator objectAnimator = ObjectAnimator.ofInt(mBackground,"alpha",255,0);        objectAnimator.setInterpolator(new DecelerateInterpolator());        objectAnimator.setDuration(1000);        objectAnimator.start();

這裡在動畫結束的時候傳入了一個 Runnable 對象,這個 Runnable 的作用就是結束詳情頁面

        activityExitAnim(new Runnable() {            @Override            public void run() {                finish();                overridePendingTransition(0, 0);            }        });

當你正在動手做的時候你可能會發現這樣一個現象,來看看

為什麼會這樣?我前面寫了一遍 blog 手勢滑動結束 Activity(一)準系統的實現,看完你就明白了。

總結

這篇 blog 的內容也不多,實現起來頁不難,只是看大家能不能想到。當然還是涉及到部分知識點:
1、屬性動畫的運用,
2、View 在螢幕上位置的擷取,可以通過
int location[] = new int[2] ;
View.getLocationOnScreen(location);
3、在 onCreate 中測量 View 的大小,不能直接擷取,需要監聽 View 的繪製,或者其他測量完成之後的回掉介面。

點擊 下載源碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.