DialogFragment 出場動畫

DialogFragment 其實就是繼承fragment,用Fragment的事物進行管理
首先在onCreate中指定DialogFragment 所對應的樣式

setStyle(DialogFragment.STYLE_NO_FRAME, R.style.DialogStyle);

    <style name="DialogStyle" parent="@android:style/Theme.Dialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@color/white</item>
    </style>

然後在onCreateView 中返回的是我們將要展示的佈局

 rootView = View.inflate(getContext(), R.layout.dialog_fragment,null);

        final ViewTreeObserver viewTreeObserver = rootView.getViewTreeObserver();
        boolean alive = viewTreeObserver.isAlive();
 //        當一個視圖樹將要繪製時,所要調用的回調函數的接口類
 // 增加監聽是爲了,加入DialogFragment的出場動畫
            viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
//                    this 就表示的這個接口的匿名實現類
                    rootView.getViewTreeObserver().removeOnPreDrawListener(this);
                    System.out.println("MyDialogFragment onPreDraw 33333333333");
                    if (circleAnimal != null){
                        circleAnimal.show(rootView);
                    }
                    return true;
                }
            });

在onstart方法中設置DialogFragment的寬高,然後設置初始化動畫對象

   @Override
    public void onStart() {
        super.onStart();
        System.out.println("MyDialogFragment onStart 44444444444444");
        ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes();
        params.width = WindowManager.LayoutParams.MATCH_PARENT;
        params.height = WindowManager.LayoutParams.MATCH_PARENT;
        getDialog().getWindow().setAttributes((WindowManager.LayoutParams) params);

        //取消過渡動畫 , 使DialogSearch的出現更加平滑
//        getDialog().getWindow().setWindowAnimations(R.style.DialogEmptyAnimation);
//      初始化動畫對象,並且設置回調監聽
        circleAnimal = new CircleAnimal();
        circleAnimal.setAnimListener(this);
    }

動畫類

public class CircleAnimal {
    //duration 運行時間
    private static final long DURATION = 200;
    //動畫監聽
    private AnimListener mListener = null;
    private Animator anim;

    public interface AnimListener {
        //退出動畫完成
        void onHideAnimationEnd();
        //出場動畫完成
        void onShowAnimationEnd();
    }
    private void actionOtherVisible(boolean isShow,final View animView){
        int[] location = new int[2];
//        獲取view在當前窗口內的絕對座標
        animView.getLocationInWindow(location);
        System.out.println("location :" + location[0]);// X 0
        System.out.println("location :" + location[1]);// y 0
//計算中心位置
        int avX = location[0] + animView.getWidth() / 2;
        int avY = location[1] + animView.getHeight() / 2;
        System.out.println("location avX" + avX +" avY " +avY);
//這個是獲取view在當前屏幕的高度,包含通知欄的高度也就是狀態欄的高度
//        int[] locaton2 = new int[2];
//        animView.getLocationOnScreen(locaton2);
//        System.out.println("locaton2 :" + locaton2[0]);// x 0
//        System.out.println("locaton2 :" + locaton2[1]);// y 90


        float startRadius;
        float endRadius;
        // Math.sqrt 這個函數是用來計算平方根的
        float maxRadius = (float) Math.sqrt((double) (avX * avX + avY * avY));
        System.out.println("maxRadius :" + maxRadius);

        if (isShow) {
            startRadius = 0f;
            endRadius = maxRadius;
        } else {
            startRadius = maxRadius;
            endRadius = 0f;
        }
//        快速實現圓形動畫縮放的api,5.0之後才引入  Reveal 顯示,展示的意思
        anim = ViewAnimationUtils.createCircularReveal(animView,0,0,startRadius, 2160f);
        animView.setVisibility(View.VISIBLE);
        anim.setDuration(500);
        anim.setInterpolator(new DecelerateInterpolator());

        anim.start();
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
//                animView.setVisibility(View.VISIBLE);
            }
        });
    }
    public void show(View rootView){
        actionOtherVisible(true,rootView);
    }
    public void hide(View rootView) {
        actionOtherVisible(false,rootView);
    }
    
//    設置對動畫的監聽
    public void setAnimListener(AnimListener listener) {
        mListener = listener;
    }
}

下面這個是玩Android 的動畫類

public class CircularRevealAnim {
//duration 運行時間
    private static final long DURATION = 200;
//動畫監聽
    private AnimListener mListener = null;
    private Animator anim;

    public interface AnimListener {

        void onHideAnimationEnd();
//動畫展示完成
        void onShowAnimationEnd();
    }

    @SuppressLint("NewApi")
    private void actionOtherVisible(Boolean isShow, View triggerView, View animView) {
//        triggerView 是所要獲取焦點的EditTextView
//        Lollipop是21
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
            if (isShow) {
//                animView 是整個rootView,
                animView.setVisibility(View.VISIBLE);
                if (mListener != null) {
                    anim.cancel();
                    anim = null;
                    mListener.onShowAnimationEnd();
                }
            } else {
                animView.setVisibility(View.GONE);
                if (mListener != null) {
                    anim.cancel();
                    anim = null;
                    mListener.onHideAnimationEnd();
                }
            }
            return;
        }

        /**
         * 計算 triggerView 的中心位置
         */
        int[] tvLocation = {0, 0};
        triggerView.getLocationInWindow(tvLocation);
//156--------12
        System.out.println("tvLocation :" + tvLocation[0] +"--------" +tvLocation[1]);
// 屏幕寬度的的0.8 倍
        int tvX = (int) (tvLocation[0] + animView.getWidth() * 0.8);
//        edittext 高度的一般
        int tvY = tvLocation[1] + triggerView.getHeight() / 2;
//        1002-----tvY84
        System.out.println("tvX :" + tvX +"-----tvY" +tvY);


        /**
         * 計算 animView 的中心位置
         */
        int[] avLocation = {0, 0};
        animView.getLocationInWindow(avLocation);
//        0--------0
        System.out.println("avLocation :" + avLocation[0] +"--------" +avLocation[1]);
        int avX = avLocation[0] + animView.getWidth() / 2;
        int avY = avLocation[1] + animView.getHeight() / 2;
//        : avX :529  avY :987
        System.out.println("avX :"+ avX + "  avY :"+ avY);
        int rippleW;
        if (tvX < avX) { //1002 < 529
             rippleW = animView.getWidth() - tvX;
        } else {
//            1002 - 0
             rippleW = tvX - avLocation[0];
        }
//      84
        int rippleH;
        if (tvY < avY) {//84 < 987
            rippleH = animView.getHeight() - tvY;
        } else {
            rippleH = tvY - avLocation[1];//84 -
        }
//        Math.sqrt(9)  返回一個正值的平方根 爲3     1002*1002 +
        float maxRadius = (float) Math.sqrt((double) (rippleW * rippleW + rippleH * rippleH));
        float startRadius;
        float endRadius;

        if (isShow) {
            startRadius = 0f;
            endRadius = maxRadius;
        } else {
            startRadius = maxRadius;
            endRadius = 0f;
        }
//         tvX :1002 ;tvY :84  endRadius :2139.183
        System.out.println("tvX :" + tvX +" ;tvY :" +tvY + "  endRadius :" + endRadius);
        anim = ViewAnimationUtils.createCircularReveal(animView, tvX, tvY, startRadius, endRadius);
        animView.setVisibility(View.VISIBLE);
        anim.setDuration(DURATION);
        anim.setInterpolator(new DecelerateInterpolator());

        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (isShow) {
                    animView.setVisibility(View.VISIBLE);
                    if (mListener != null) {
                        mListener.onShowAnimationEnd();
                    }
                } else {
                    animView.setVisibility(View.GONE);
                    if (mListener != null) {
                        mListener.onHideAnimationEnd();
                    }
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        anim.start();
    }

    public void show(View triggerView, View showView) {
        actionOtherVisible(true, triggerView, showView);
    }

    public void hide(View triggerView, View hideView) {
        actionOtherVisible(false, triggerView, hideView);
    }

    public void setAnimListener(AnimListener listener) {
        mListener = listener;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章