PopWindow 展开带阴影平移动画

前:在看设计图的时候,设计师说需要一个弹出层在指定位置,渐出,背景带阴影层,第一个想到的是 popWindow  ,但是pop 并没有阴影层,直接是一层覆盖在上面。仔细一想带阴影也是可以,但是渐渐出现的动画如何和背景阴影协同展示,是个问题。所以查阅了一些资料,以及填了一些坑。完成了最终的效果。效果如下:

1.首先需要注意的是  showPopupWindow 这个方法

在不同android系统上面展示的效果是不一样的,这是适配的一个坑。

在7.0 以下的手机,pop 设置 MATCH_PARENT,是完全没有问题的,在7.0以上的手机 会发现 pop 直接顶到父布局的顶端了。完全没有在指定位置的下面。

//这个属性 在 6.0和7.0以上处理不同,6.0 就直接在下面,不管pop 大小,7.0pop太大,就会找父类view

下面是我的处理方法:动态的设置pop 的高宽

private void initView(QuoInfoObject.QuoInfo quoInfo) {
        setWidth(ViewGroup.LayoutParams.MATCH_PARENT);

        if (Build.VERSION.SDK_INT < 24) {
            setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
        } else {
            float density = mContext.getResources().getDisplayMetrics().density;
            Log.d("QuotationDescWindow","density="+density);

            int height;
            if(density == 2.5){
                height = ScreenUtils.getScreenHeight(mContext) - ScreenUtils.dip2px(mContext, 110) + topScrollDis;
            }else {
                height = ScreenUtils.getScreenHeight(mContext) - ScreenUtils.dip2px(mContext, 143) + topScrollDis;
            }

            setHeight(height);
        }

        .....
        ..

        setOutsideTouchable(true);
        setFocusable(true);
    }
height = ScreenUtils.getScreenHeight(mContext) - ScreenUtils.dip2px(mContext, 110) + topScrollDis;

ScreenUtils.dip2px(mContext, 110)  固定位置距离顶部的距离

topScrollDis 这个是顶部滚动的距离,动态控制的。

 

2.解决动画的显示问题,参考了相关的资料

这里处理采用属性动画,补间动画不能满足要求。

    //显示
    public void showPopupWindow(View parent, int xOff, int yOff) {
        if (!this.isShowing()) {

            showAsDropDown(parent, xOff, yOff);

            //执行进入动画,这里主要是执行列表下滑,背景变半透明
            AnimUtils.createAnimation(true, contentView, rootView, null);
        } else {
            dismissPopup();
        }
    }

 

AnimUtils.createAnimation:就是简单的一个属性动画的展示,相关代码如下

 /**
     * @param isIn          动画类型,进入或消失
     * @param rootView      根布局,主要用来设置半透明背景
     * @param target        要移动的view
     * @param animInterface 动画执行完毕后的回调
     */
    public static void createAnimation(final boolean isIn, final View rootView, final View target,
                                       final AnimInterface animInterface) {
        final int toYDelta = ScreenUtils.getViewHeight(target);//测量布局高度
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(isIn ? -toYDelta : 0, isIn ? 0 : -toYDelta);
        valueAnimator.setDuration(isIn ? ANIMATION_IN_TIME : ANIMATION_OUT_TIME);
        valueAnimator.setRepeatCount(0);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float currentValue = (Float) animation.getAnimatedValue();
                target.setY(currentValue);
                rootView.setAlpha(1 - Math.abs(currentValue) / animation.getDuration());
            }
        });

        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                if (animInterface != null) {
                    animInterface.animStar();
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                if (animInterface != null) {
                    animInterface.animEnd();
                }
            }
        });
        valueAnimator.start();
    }

3.pop 布局的xml 显示

PopWindow 展开带阴影平移动画_第1张图片

这个cover 是填充布局下面的留白和方便点击空白处 关闭

 

4.完整的代码 

4-1:

public class QuotationDescWindow extends PopupWindow {
    private Context mContext;
    private View contentView;//弹出框的根布局,可以监听其点击事件,达到点击阴影消失弹框的效果
    private LinearLayout rootView;
    private TextView contentTv;
    private CircularStatisticsView ringView;
    private TextView upConts,downConts,fairConts,enterMonety,enterFont;
    private TextView weekRadio,monthRadio,seasonRadio,yearRadio;

    private int topScrollDis;
    private boolean isAnimalRunning = false;

public QuotationDescWindow(Context context, int scrollDis, QuoInfoObject.QuoInfo quoInfo) {
        super(context);
        mContext = context;
        topScrollDis = scrollDis;

        initView(quoInfo);
    }

    private void initView(QuoInfoObject.QuoInfo quoInfo) {
        setWidth(ViewGroup.LayoutParams.MATCH_PARENT);

        if (Build.VERSION.SDK_INT < 24) {
            setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
        } else {
            //45+78 + 20 = 143
            float density = mContext.getResources().getDisplayMetrics().density;
            Log.d("QuotationDescWindow","density="+density);

            int height;
            if(density == 2.5){
                height = ScreenUtils.getScreenHeight(mContext) - ScreenUtils.dip2px(mContext, 110) + topScrollDis;
            }else {
                height = ScreenUtils.getScreenHeight(mContext) - ScreenUtils.dip2px(mContext, 143) + topScrollDis;
            }

            Log.d("QuotationDescWindow","height="+height);

            setHeight(height);
        }

        //这里的xml 就是第三点贴出来的
        contentView = LayoutInflater.from(mContext).inflate(R.layout.pop_quo_desc_layout, null);
        setContentView(contentView);//设置布局
        setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

        //相关控件的获取和数据的处理就不贴了
        ....
        ....

        setOutsideTouchable(true);
        setFocusable(true);

        contentView.findViewById(R.id.pop_desc_cover).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dismiss();
            }
        });
    }

    
    //显示
    public void showPopupWindow(View parent, int xOff, int yOff) {
        if (!this.isShowing()) {
            //这个属性 在 6.0和7.0以上处理不同,6.0 就直接在下面,不管pop 大小,7.0pop太大,就会找父类view
            //https://blog.csdn.net/xx23x/article/details/53557731
//            int[] positon = new int[2];
//            parent.getLocationOnScreen(positon);
//            showAsDropDown(parent,positon[0] + xOff,positon[1] +yOff);
            showAsDropDown(parent, xOff, yOff);

            //执行进入动画,这里主要是执行列表下滑,背景变半透明
            AnimUtils.createAnimation(true, contentView, rootView, null);
        } else {
            dismissPopup();
        }
    }

    //消失
    public void dismissPopup() {
        super.dismiss();// 调用super.dismiss(),如果直接dismiss()会一直会调用下面的dismiss()
    }


    @Override
    public void dismiss() {
        if (isAnimalRunning) { //防止重复点击,动画多次执行
            return;
        }

        //执行退出动画,列表上滑退出,同时背景变透明
        AnimUtils.createAnimation(false, contentView, rootView, new AnimUtils.AnimInterface() {
            @Override
            public void animStar() {
                isAnimalRunning = true;
            }

            @Override
            public void animEnd() {
                isAnimalRunning = false;
                dismissPopup();//动画执行完毕后消失

            }
        });
    }

    
}

 

4-2:

相关调用

private void showPopView() {
        if (quoInfoData == null) {
            return;
        }

        QuotationDescWindow quotationDescWindow = new QuotationDescWindow(QuotationDetailActivity.this, topScrollDis, quoInfoData);
        quotationDescWindow.showPopupWindow(subTopView, 0, 0);
        quotationDescWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                setDescEnterIcon(false);
            }
        });
    }

 

你可能感兴趣的:(android-杂记)