dialog设置动画及属性动画的部分说明

最近做了一个新需求,在屏幕中间弹出一个dialog,然后dialog缩放并移动到某个指定的位置。

常见于进入一个界面,然后弹出一个提示弹框,然后弹框消失的时候,移动到左上角,告诉用户弹框在这个地方。也有点类似于购物车那种,点击购买了某样东西,然后抛物线进入购物车,购物车用的是贝塞尔曲线,我这个就简单一点直接一个平移动画。

先说一下碰到的问题:

  1. 怎么给dialog设置动画。
  2. 属性动画的说明。
  3. 动画在移动的时候,到了某个位置消失了。
  4. dialog在用户点击返回键的处理。

下面是针对我的问题,一个个解决。

  • 设置动画

一般我们在做dialog的时候,最常用的是设置dialog的进入和出去的动画,这个一般在onCreateDialog的时候,通过window去设置。就是下面的代码。

Window window = dialog.getWindow();
if (window != null) {
    window.setWindowAnimations(R.style.dialog_animation);
}
这里顺便带一句,如果要设置或者取消外部点击消失,用这个方法dialog.setCanceledOnTouchOutside(true);这个方法一般也是在onCreateDialog的时候设置就可以了。
但是,通过设置style我们无法很精确的移动到我们需要的坐标位置,而且移动位置如果有一点变化,可能需要重新计算等问题。
所以,我们需要在代码中,通过计算使动画移动的位置更准确。这个时候就需要思考怎么给整个dialog设置动画了。
一开始我一直在考虑怎么给整个dialog设置动画,然后通过getdialog获取到dialog的对象以后,无法把animator设置给dialog,提示我说动画只能针对view设置。后来突然发现,思路进入牛角尖了,dialog的view不就是view嘛,然后我就直接通过getview或者可以通过获取dialog的最外层布局即可获取到需要设置动画的对象。到这里,我们的动画就有了思路。
  • 属性动画

动画的选择方面,我这边使用的是属性动画ObjectAnimator。属性动画会直接改变控件的属性,即在动画完成以后,实际位置/大  小/透明度都发生了改变的,常用的属性动画有缩放/平移/渐变度的改变。这边稍微说明一下,详细可以百度属性动画自行了解。我们这次的需求只需要使用一个缩放 + 平移即可。

ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(getView(), "scaleX",1, 0.1f); 
说明一下这里的参数,第一个是需要做动画的view,第二个scaleX是针对x轴进行缩放,后面的参数是变化的值,如我这里,从原大小变成0.1倍的大小,当然你也可以从0 -> 1.0f 。你也可以设置(0.1f, 1.0f, 0.5f, 2.0f)这里可以传多个值。同理可以设置scaleY。针对Y进行变换。缩放动画就这几个。
ObjectAnimator transXAnim = ObjectAnimator.ofFloat(getView(), "translationX",0, tranX);
这个是平移动画,前2个参数相同。后面的参数说明一下,我使用的时候,也是很久没用了,最开始以为是从0的位置移动到tranX这个坐标,后来发现是向x轴移动tranX位置。所以我们需要计算,动画需要在x上移动的距离。
int tranX = tranToX - tranStartX; (移动距离 = 目标位置x点坐标 - 当前位置x点坐标) 。然后把这个移动距离设置到动画数值那里即可,类似旋转的。当然也可以设置多个值,比如先右X移动100个距离,然后再向左移动200个位置,然后再向右移动50个位置。(getView(), "translationX",100, -200,50);(X移动时正为向右,负数为向左移动。同理Y轴移动的时候,正为向下,负数向上移动)其余就不过多介绍属性动画了,设置一个动画持续时间,设置一个动画循环的次数,通过.playTogether(动画A, 动画B); start()动画即可。

突然想起来了,这里目标位置的坐标获取说明一下:目标位置一般都是移动到某个view上。我这边是通过下面这个方法
int[] location = new int[2];
mTargerView.getLocationInWindow(location);
通过获取目标位置在屏幕中的位置,这样会比较准备。当然具体做动画的时候要根据移动的位置计算一下view的宽高。
  • 移动以后消失,动画的部分细节(这个是这里重点需要说明的)

动画执行的时候碰到或者有跳动,或者有消失等等问题。对了,这里需要说一下,要把原来的dialog移除的时候的动画移除了,不然dialog在移除的时候还有一个动画,即最开始说的常用dialog进入和退出时的动画。最开始猜想可能是位置计算有错,我一开始是毛估估的计算了动画移动的位置,没有按照上面说的精确计算,这样可以解决动画跳动的问题。然后就是动画走到快要结束的地方有一个消失的情况,一开始也去考虑是不是位置算错了。后来多次验证发现和距离应该没关系,动画的移动距离没问题。我在没有调用dialog的dismiss方法时,动画执行到最后ui也消失了,后来突然想到,会不会和dialog的整体宽高有关。然后就修改了整个dialog为matchparent,再设置了一个透明的背景。重新执行动画,问题解决。那我这里就猜想,动画执行时,只能在view所绘制的区域内,超出了以后就会消失。

  • 返回键的处理

最后把我们上面写的消失的动画设置到dialog的关闭按钮响应上即可。其余的就剩一些优化了,比如dialog销毁的时候动画的回收,dialog多次调用覆盖等问题。然后就是用户不去点击我们设置的关闭按钮,直接通过手机的返回按钮来关闭dialog,由于我们不是在dialog的dismiss()方法里面设置的动画,这就需要我们去设置dialog在点击返回按钮的回掉了。一开始我是对整个Activity的back事件进行判断,后来发现dialog自己有一个setOnKeyListener()的方法,通过重写里面的onKey方法,这样可以在dialog显示的时候监听到用户点击返回键。

getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
            Log.e("xnm", "KEYCODE_BACK");
            showDismissScaleAnim();
            return true;
        }
        return false;
    }
});
一开始是没有增加(event.getAction() == KeyEvent.ACTION_UP)判断,然后在看日志的时候发现日志打印了两遍,后来突然想到了,可能是按下和抬起的事件都监听到了,然后增加了一个判断,解决两次回调的问题。

好了,本期的分享到这里就结束了,谢谢大家,有问题请指正。

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页