美文网首页
menu展开动画(属性动画)

menu展开动画(属性动画)

作者: 准备流浪的雪 | 来源:发表于2019-06-20 23:16 被阅读0次

    好伤心啊,webm转化成的pdf在简书上居然无法正常播放,我要怎么给宝宝们展示动态效果呢,蓝瘦香菇...上截图~~


    Screenshot_1561041389.png Screenshot_1561041395.png Screenshot_1561041444.png

    嗯啦嗯啦,安啦,那个🍵在冒烟儿,是均匀分布的啦!
    怎么实现的呢?so easy!
    布局首先是个FrameLayout,里面有包含8个imageview,一起堆在左上角,布局文件如下:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/iv_b"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_margin="10dp"
            android:contentDescription="@null"
            android:src="@drawable/b" />
    
        <ImageView
            android:id="@+id/iv_c"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_margin="10dp"
            android:contentDescription="@null"
            android:src="@drawable/c" />
    
        <ImageView
            android:id="@+id/iv_d"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_margin="10dp"
            android:contentDescription="@null"
            android:src="@drawable/d" />
    
        <ImageView
            android:id="@+id/iv_e"
            android:layout_width="50dp"
            android:layout_margin="10dp"
            android:layout_height="50dp"
            android:contentDescription="@null"
            android:src="@drawable/e" />
    
        <ImageView
            android:id="@+id/iv_f"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_margin="10dp"
            android:contentDescription="@null"
            android:src="@drawable/f" />
    
        <ImageView
            android:id="@+id/iv_g"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_margin="10dp"
            android:contentDescription="@null"
            android:src="@drawable/g" />
    
        <ImageView
            android:id="@+id/iv_h"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_margin="10dp"
            android:contentDescription="@null"
            android:src="@drawable/h" />
    
        <ImageView
            android:id="@+id/iv_a"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:contentDescription="@null"
            android:src="@drawable/a" />
    </FrameLayout>
    

    然后在我们的页面里面把这些imageView放到一个集合里面:

     private int[] resIds = {R.id.iv_a, R.id.iv_b, R.id.iv_c, R.id.iv_d, R.id.iv_e,
                R.id.iv_f, R.id.iv_g, R.id.iv_h};
        private List<ImageView> imageViews = new ArrayList<>();
    
      for (int resId : resIds) {
                ImageView imageView = findViewById(resId);
                imageView.setOnClickListener(this);
                imageViews.add(imageView);
            }
    

    然后对iv_a这个设置一个点击事件,点一下展开menu,再点一下关闭menu。
    一言不合上代码....
    先说垂直展开菜单这个,设置Y轴偏移量根据i值变化,就可以程序上图那种萌萌哒的状态啦:

     private void openMenu() {
            for (int i = 1; i < resIds.length; i++) {
                ObjectAnimator animator = ObjectAnimator.ofFloat(imageViews.get(i), "translationY",
                        0F, i * 300F);
                animator.setDuration(500);
                animator.setInterpolator(new AccelerateInterpolator());
    //            animator.setStartDelay(i*300);
                animator.start();
            }
            expand = true;
        }
    

    关上!把这个菜单关上就是把所有的偏移量从现在的偏移量恢复成0:

       private void closeMenu() {
            for (int i = 1; i < resIds.length; i++) {
                ObjectAnimator animator = ObjectAnimator.ofFloat(imageViews.get(i), "translationY",
                        i * 300F, 0F);
                animator.setDuration(500);
                animator.setInterpolator(new AccelerateInterpolator());
    //            animator.setStartDelay(i*300);
                animator.start();
            }
            expand = false;
        }
    
    

    这里我解释一下 ObjectAnimator.ofFloat里面的几个参数,第一个参数是target,就是需要进行动画操作的目标,没错,就是这些imageView啦,第二个参数,需要改变的属性,没错,就是我们的Y轴偏移量TranslationY啦,后面的属性就是values,就是我们的属性值从哪个值变化到哪个值,可以清楚地看到展开菜单和关闭菜单的不同就是属性值的变化不同,展开是从0→i300,关闭时从i300→0。

    setDuration就是动画从开始到结束这个时间长短。
    setInterpolator就是动画的插值器,设置动画变化的规律,有9个默认的插值器,这里用的是默认的加速插值器AccelerateInterpolator,还有减速啊,回弹啊等等之类的,好的插值器链接参照:https://www.jianshu.com/p/88740cba25e6
    一般插值器是为了让动画效果更接近现实,so,根据自身需要决定是否使用。

    好,下一个,扇形展开菜单!

    扇形的怎么展开呢?简单一看就是不仅有Y轴的偏移量还有X轴的偏移量!要让他呈扇形均匀展开,就是把扇形平均分成imageViews.size() - 1份,回顾一下数学:

    弧度的定义:弧长等于圆半径长的弧所对的圆心角为1弧度,弧度没有单位。
    即弧度=弧长/半径=l/r,因此,若弧度=π,弧长=πr=圆周的一半,此时恰好为一个半圆,圆心角180,也就是说π=180,1°=π/180
    

    所以我们的角度计算公式为:

    angle = (float) Math.PI / (2 * (imageViews.size() - 1));//(π/2)/(imageViews.size() - 1)
    

    三角函数计算x轴y轴的偏移量:

     float x = (float) (r * Math.sin(i * angle));
     float y = (float) (r * Math.cos(i * angle));
    

    不懂得同学请自己摸出草稿本画三角形
    三角形的展开和收起动画:

    
        private void angleOpenMenu(float angle, float r) {
            for (int i = 1; i < resIds.length; i++) {
                float x = (float) (r * Math.sin(i * angle));
                float y = (float) (r * Math.cos(i * angle));
                PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", 0F, x);
                PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", 0F, y);
                ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageViews.get(i),
                        translationX, translationY);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.setDuration(500).start();
            }
            expand = true;
        }
    
        private void closeOpenMenu(float angle, float r) {
            for (int i = 1; i < resIds.length; i++) {
                float x = (float) (r * Math.sin(i * angle));
                float y = (float) (r * Math.cos(i * angle));
                PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", x, 0F);
                PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", y, 0F);
                ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageViews.get(i),
                        translationX, translationY);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.setDuration(500).start();
            }
            expand = false;
        }
    

    细心的同学可以看到里面多了个PropertyValuesHolder,这个是用于组合多个动画,也可以像垂直展开动画一样单独写,如果需要定义动画顺序,比如先Y轴便宜再X轴偏移,或者Z轴和Y轴一起偏移,就需要使用AnimatorSet。

    简单说一下AnimatorSet:

    AnimatorSet.playTogether//动画一起播放;
    AnimatorSet.playSequentially//动画按照顺序播放;
    AnimatorSet.play(translationX).with(translationY)//动画X和Y一起播放;
    AnimatorSet.play(translationY).after(translationX)//动画Y在动画X之后执行
    

    好,到此结束。
    有不对的地方请指正,O(∩_∩)O谢谢。

    相关文章

      网友评论

          本文标题:menu展开动画(属性动画)

          本文链接:https://www.haomeiwen.com/subject/cnmsqctx.html