popupWindow的使用

第一次在项目中使用属性动画来做popupWindow,遇到了一大堆问题,耽误了好久,终于完了,写个总结。

理解

什么叫属性动画呢?
我的理解就是一个控件或者多个控件在一定的范围内进行各种运动,它不会回头,而是一如既往的向前运动,与帧动画不一样。
打个比较形象的例子,一个人沿着操场跑步,帧动画是100米的往返跑,属性动画则是沿着整个操场跑,也许会经过原点,但是它没有一个折返的过程。属性动画是一个过程,它适合一个长时间的动画效果。

在popupWindow中使用的时候这里有几个问题需要注意:
1、ObjectAnimator方法的使用
2、OvershootInterpolator等补间器(插值器)的使用
3、如果需要用到overridePendingTransition,则要注意参数的理解


ObjectAnimator的使用

这里要先说一下这个PropertyValuesHolder

PropertyValuesHolder这个类拥有关于属性的信息和动画期间需要使用的值。它可以用来和ObjectAnimator或ValueAnimator一起创建可以并行操作PropertyValuesHolder不同属性的animator。

对PropertyValuesHolder的初始化:

final PropertyValuesHolder p = PropertyValuesHolder.ofFloat("translationY", 0, xF);
//final 这里是为了把方法锁定,防止任何继承类修改它的意义和实现。translationY 是沿Y轴翻转,0是起始点的位置,xF是从起始点移动到指定点的距离

然后就是对p的使用

ObjectAnimator animatorStart =ObjectAnimator.ofPropertyValuesHolder(textView, p);
//属性动画ObjectAnimation,(x,x,x)为动画效果,在PropertyValuesHolder中设置
animatorStart.setInterpolator(new OvershootInterpolator());//插值器
animatorStart.setDuration(350);//动画的速度
animatorStart.start();
//textView 为控件集合在重新定义的textView

OvershootInterpolator等补间器(插值器)的使用

这里传上一副比较常见的补间器图:

补间器:拆开来说,补——补充、间——时间。连在一起就是补充时间的一个工具,那么补充的是什么时间呢?用在这里的花就是说补充动画的时间,效果就是在原有的动画基础上再增加一些动画,这样会使得动画更有活力,更好看。


overridePendingTransition

 overridePendingTransition(int, out);//()括号内的int,out是开始和结束的意思。例如
 (R.anim.push_right_in,R.anim.push_right_out)。一个动画开始的效果,一个是动画结束的效果。
 如果光是这样用的话,会发现滑动后会出现黑屏的问题,这个时候就要注意把第二个参数换成一个透明度,这样就好了!

R.anim.push_right_in:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fromXDelta="100%p"
        android:toYDelta="0"
        />
</set>

push_alpha_in.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android">

    <alpha
        android:fromAlpha="1"
        android:toAlpha="1"
        android:duration="300"
        />
</set>

PopupWindow主要的几个方法:

//这里我是继承的封装的BasePopupWindow调用的布局
    @Override
    protected int getLayoutRes() {
        return R.layout.pop_contribute;
    }
     @Override
    protected void initPopupWindow(Activity activity, View contentView) {
        //获取popupwindow的高度与宽度
        int width = DisplayUtil.getScreenWidth(activity);
        int height = DisplayUtil.getScreenHeight(activity);
        Logger.i("width =" + width + "   height =" + height);
//        // 设置弹出窗体的宽
        setWidth(width);
//        // 设置弹出窗体的高
        setHeight(height);

        .............

        setFocusable(true);
        setOutsideTouchable(true);
        setBackgroundDrawable(null);
        setTouchable(true);
}

/**
     * 开始动画
     */
    private void startAnimation() {
        for (int i = 0; i < textViewList.size(); i++) {
            final View textView = textViewList.get(i);
            new Handler().postDelayed(new Runnable() {//延迟发送postDelayed
                @Override
                public void run() {
                    textView.setVisibility(View.VISIBLE);
//                    ObjectAnimator animatorStart = ObjectAnimator.ofPropertyValuesHolder(textView, p);//属性动画ObjectAnimation,(x,x,x)为动画效果,在PropertyValuesHolder中设置
//                    animatorStart.setInterpolator(new OvershootInterpolator());//伸缩弹力动画
//                    animatorStart.setDuration(350);//进入的时间
//                    animatorStart.start();
                    int[] location = new int[2];//将屏幕分成2份,location[0]是投稿控件所占满的部分,location[1]是整个屏幕减去投稿控件的部分
                    textView.getLocationInWindow(location); //获取在当前窗口内的绝对坐标
                    textView.getLocationOnScreen(location);//获取在整个屏幕内的绝对坐标
                    float curTranslationY = textView.getTranslationY();
                    Logger.i("curTranslationY=" + curTranslationY + "    " + textView.getBottom());
                    ObjectAnimator animator = ObjectAnimator.ofFloat(textView, "translationY", DisplayUtil.getScreenHeight(activity) - location[1], 0f);
                    animator.setInterpolator(new OvershootInterpolator());//伸缩弹力动画-插值器
                    animator.setDuration(250);
                    animator.start();
                }
//                }
            }, 120 * i);//每一个控件的间隔时间
        }
    }

    /**
     * * 关闭动画
     */
    private void stopAnimation() {
        //PropertyValuesHolder这个类拥有关于属性的信息和动画期间需要使用的值。PropertyValuesHolder对象
        // 可以用来和ObjectAnimator或ValueAnimator一起创建可以并行操作不PropertyValuesHolder同属性的animator。
//        final PropertyValuesHolder p = PropertyValuesHolder.ofFloat("translationY", 0, 500F);
        for (int i = textViewList.size() - 1; i >= 0; i--) {
            final View textView = textViewList.get(i);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    int[] location = new int[2];
                    textView.getLocationInWindow(location); //获取在当前窗口内的绝对坐标
                    textView.getLocationOnScreen(location);//获取在整个屏幕内的绝对坐标\
                    float curTranslationY = textView.getTranslationY();
                    Logger.i("curTranslationY=" + curTranslationY + "    " + textView.getBottom());
                    ObjectAnimator animator = ObjectAnimator.ofFloat(textView, "translationY", 0f, location[1]);
                    animator.setInterpolator(new OvershootInterpolator());//伸缩弹力动画-插值器
                    animator.setDuration(1500);
                    animator.start();
                }
            }, 100 * (textViewList.size() - 1 - i));
        }
    }

MainActivity:

new ContributePopupWindow(MainActivity.this).showPopupWindow(xx);
//xx为点击PopupWindow的控件

最后,这里我遇到了几个坑,
1、setAnimationStyle(android.R.style.Animation_InputMethod);
popupWindow的动画与控件动画应该是会冲突,这样会产生卡顿,毕竟是同步执行的,如有错误请见谅。
2、textViewList = new ArrayList<>();注意集合的初始化地方和其List<>中类型的设置。
3、setBackgroundDrawable(null);这个属性必须设置,不然会出现非常无语的问题。()中的参数可以自行设置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值