自己实现floatactionbutton展开折叠功能

来源:互联网 发布:淘宝客一淘活动广场 编辑:程序博客网 时间:2024/05/17 06:53

         之前总会见到那种功能,好比屏幕右下角有个按钮,点击之后向上弹出一系列菜单按钮,然后点击菜单按钮会实现自己的业务并且同时这些菜单会收起到左下角。github上面有个关于这个功能实现的库,但是最近自己想要实现这样的功能,其实实现这个功能最主要的就是动画的应用了。

         我们看到的那种效果都是点击一个按钮之后,别的菜单按钮从其底部依次弹出,但是又不是绝对的一个接着一个的弹出,而是有一定的时差的,然后收回也是一样子的。

         然后说下思路:有几个菜单肯定就是会有几张图片的,布局里面我用的是一个相对布局,然后预览时候是各自覆盖的,除了最初展示的那个菜单图片,别的被覆盖的图片的透明度都是0。当点击最初的展示的菜单图片时候,首先是每个图片沿着y轴向上运动一段距离到达指定位置,然后是alpha透明度从0变为1以及scale从0变为1;同样收回的时候是一个相反的过程,首先是各个item需要alpha从1变到0以及scale从1变到0,然后在沿着y轴运动一段距离返回至其初始位置。然后我们看下代码关键代码:

//view的弹出动画,首先是将view移动至其该所在的位置,其次是大小以及 透明度的变化了    private AnimatorSet doAnimOpenItem(View view, int index) {        float distance = index * ITEM_DISTANCE;        AnimatorSet animatorSet = new AnimatorSet();        animatorSet.play(                ObjectAnimator.ofFloat(view, "alpha", 0, 1))                .with(ObjectAnimator.ofFloat(view, "scaleX", 0f, 1))                .with(ObjectAnimator.ofFloat(view, "scaleY", 0f, 1))                .after(ObjectAnimator.ofFloat(view, "translationY", 0, distance));        //设置的延时时间恰好是在前一个动画执行结束前 后一个动画就开始执行,给人一种连贯的感觉        animatorSet.setStartDelay(index * 40);        animatorSet.setDuration(50);        return animatorSet;    }
这段代码每个view弹出动画执行的方法,其中的ITEM_DISTANCE是每个Item之间的距离,其中很关键的一点是我们设置的延时,即setStartDelay,如果不设置这个就不会有那种连贯的感觉,具体可以看效果。

//点击之后执行展开动画的方法    private void doAnimOpen() {        //如果正在执行动画则返回        if (isAnimating) {            return;        }        isAnimating = true;        isOpen = true;        AnimatorSet animatorSet = new AnimatorSet();        animatorSet.playTogether(                doAnimOpenItem(activityFloatmenuBinding.startIv2, 1),                doAnimOpenItem(activityFloatmenuBinding.startIv3, 2),                doAnimOpenItem(activityFloatmenuBinding.startIv4, 3),                doAnimOpenItem(activityFloatmenuBinding.startIv5, 4));        animatorSet.setInterpolator(new OvershootInterpolator());        animatorSet.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {            }            @Override            public void onAnimationEnd(Animator animation) {                //动画执行完毕将其置为false                isAnimating = false;            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });        animatorSet.start();    }
调用这个方法目的是为了让每个view都开始执行展开动画,可以看到上面用的是playTogether的,就是每个动画都是同时开始的,这个时候我们给每个动画设置的延时就起作用了,每个动画开始的延迟时间是跟其所在的位置是有关的,位置越靠后延时越久。其实本来我这里是用的顺序执行的, 即playSequentially的,即每个动画顺序执行,但是那样看起来没有连贯性,所以改成了playTogether然后给每个Item的动画加上延迟实现了效果。上面有个boolean类型的isAnimating,它的作用就是防止用户连续点击那个初始展示的图片,然后动画一直执行,并且还会乱序。
//每个Item关闭时候执行的动画    private AnimatorSet doAnimCloseItem(View view, int index) {        float distance = index * ITEM_DISTANCE;        AnimatorSet animatorSet = new AnimatorSet();        //首先是将view大小变为0,以及透明度变为0,然后将其移动至原来的位置        animatorSet.play(                ObjectAnimator.ofFloat(view, "alpha", 1, 0))                .with(ObjectAnimator.ofFloat(view, "scaleX", 1, 0f))                .with(ObjectAnimator.ofFloat(view, "scaleY", 1, 0f))                .before(ObjectAnimator.ofFloat(view, "translationY", distance, 0));        animatorSet.setDuration(50);        //关闭时候恰好跟开始时候是相反的,所以延迟时间是越靠后越少了        animatorSet.setStartDelay((5 - index) * 40);        return animatorSet;    }
这里唯一的不同就是先执行的Item透明度以及大小的动画然后执行的是移动的动画,因为每个Item都是同时执行的所以如果先移动的话会有重叠的情况,同样延时也是也是随着index的增大越来越小的了。
//所有Item执行关闭动画的方法    private void doAnimClose() {        //如果正在执行动画则返回        if (isAnimating) {            return;        }        isAnimating = true;        isOpen = false;        AnimatorSet animatorSet = new AnimatorSet();        animatorSet.playTogether(                doAnimCloseItem(activityFloatmenuBinding.startIv5, 4),                doAnimCloseItem(activityFloatmenuBinding.startIv4, 3),                doAnimCloseItem(activityFloatmenuBinding.startIv3, 2),                doAnimCloseItem(activityFloatmenuBinding.startIv2, 1));        animatorSet.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {            }            @Override            public void onAnimationEnd(Animator animation) {                //动画执行完毕将其置为false                isAnimating = false;            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });        animatorSet.start();    }
最后这个方法是让每个view都执行折叠方法,跟让每个view都执行展开动画的差不多。

       具体的代码就到这里了,其实就是属性动画的应用,代码已经上传github,可以点击这里查看。如果不对之处,欢迎批评指正。



阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 玉龙雪山无人登顶 玉龙雪山海拔多少米 提携玉龙为君死 玉龙雪山温度 玉龙股份股票 红山文化玉龙 玉龙雪山在哪里个城市 601028玉龙股份 玉龙雪山在什么地方 丽江玉龙发生山火 玉龙雪山门票价格 赤峰玉龙机场 玉龙雪山游玩攻略 云南玉龙雪山海拔 玉龙雪山海拔多少米高 玉龙雪山多高 玉龙雪山4680图片 玉龙溪原始森林公园 赤峰玉龙论坛 玉龙雪山一日游报价 玉龙雪山纯玩团 玉龙雪山一日游多少钱 玉龙雪山氧气瓶多少钱 玉龙雪山 纯玩 玉龙雪山票价 玉龙草的价格 玉龙油多少钱 去玉龙雪山要多少钱 玉龙雪山旅游路线 玉龙雪山附近住宿 玉龙雪山婚纱照 玉龙雪山缆车价格 玉龙雪山缆车 玉龙雪山 团购 玉龙雪山蓝月谷一日游 梅里雪山 玉龙雪山 玉龙股份股票行情 玉龙雪山演出 玉龙雪山当地一日游 玉龙雪山自助一日游 玉龙雪山 旅游攻略