美文网首页VuandroidAndroid知识
Android开罐头———快速打造扇形卫星菜单

Android开罐头———快速打造扇形卫星菜单

作者: youyuge | 来源:发表于2017-06-09 20:06 被阅读866次

    属性动画,快速打造,练手用

    image.png

    预览图:

    menu.gif

    一、制作圆形图标

    很方便地利用as自动生成圆形图标:

    • 右击res,选择Image Asset:
    image.png
    • 选择Launcher Icons,然后选Square,其余自己调整:
    image.png

    现在,mipmap中有了相关图片~~
    当然,普通icon加个shape也是很方便的~

    二、布局文件

    很简单,新建一个布局文件,记得把加号图标放最下面,这样就能遮住别的图标,直接上代码了:

    //layout/circle_menu_layout.xml

    <?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"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/circle_menu_button_2"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="15dp"
            android:layout_marginRight="15dp"
            android:src="@mipmap/ic_edit1" />
    
        <ImageView
            android:id="@+id/circle_menu_button_3"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="15dp"
            android:layout_marginRight="15dp"
            android:src="@mipmap/ic_star" />
    
        <ImageView
            android:id="@+id/circle_menu_button_4"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="15dp"
            android:layout_marginRight="15dp"
            android:src="@mipmap/ic_cloud" />
    
        <ImageView
            android:id="@+id/circle_menu_button_5"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="15dp"
            android:layout_marginRight="15dp"
            android:src="@mipmap/ic_look" />
    
        <ImageView
            android:id="@+id/circle_menu_button_1"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="12dp"
            android:layout_marginRight="12dp"
            android:src="@mipmap/ic_add" />
    
    </FrameLayout>
    

    在总的布局文件中,直接include引入即可:

     <include layout="@layout/circle_menu_layout" />
    

    三、代码中使用属性动画

    • 首先定义变量,分别是资源id数组,图片队列,用来标明开关状态的标志位
        //扇形菜单按钮
        private int res[] ={R.id.circle_menu_button_1,R.id.circle_menu_button_2,R.id.circle_menu_button_3,R.id.circle_menu_button_4,R.id.circle_menu_button_5};
        private ArrayList<ImageView> imageViews = new ArrayList<>();
        //菜单是否展开的flag,false表示没展开
        private boolean mFlag = false;
    
    • 利用for循环初始化图标实例
     for (int i = 0; i < res.length; i++) {
                ImageView imageView = (ImageView) mContentView.findViewById(res[i]);
                imageView.setOnClickListener(this);
                imageViews.add(imageView);
            }
    
    • 在点击事件onClick()中,判断开关状态后,开启进入或者退出的动画方法
    case R.id.circle_menu_button_1:
                    if (mFlag == false){
                        showEnterAnim(100); //100为扇形半径dp值
                    }else {
                        showExitAnim(100);
                    }
                    break;
    
    • 下面来看看最重要的showEnterAnim()方法:
    //显示扇形菜单的属性动画
        private void showEnterAnim(int dp) {
        //for循环来开始小图标的出现动画
            for (int i = 1; i < res.length; i++) {
                AnimatorSet set = new AnimatorSet();
                double x = -Math.cos(0.5/(res.length-2)*(i-1)*Math.PI)* Utils.dip2px(mContext,dp);
                double y = -Math.sin(0.5/(res.length-2)*(i-1)*Math.PI)* Utils.dip2px(mContext,dp);
                set.playTogether(
                        ObjectAnimator.ofFloat(imageViews.get(i),"translationX",(float)(x*0.25),(float)x),
                        ObjectAnimator.ofFloat(imageViews.get(i),"translationY",(float)(y*0.25),(float)y)
                        ,ObjectAnimator.ofFloat(imageViews.get(i),"alpha",0,1).setDuration(2000)
                );
                set.setInterpolator(new BounceInterpolator());
                set.setDuration(500).setStartDelay(100*i);
                set.start();
            }
    //转动加号大图标本身45°
            ObjectAnimator rotate = ObjectAnimator.ofFloat(imageViews.get(0),"rotation",0,45).setDuration(300);
            rotate.setInterpolator(new BounceInterpolator());
            rotate.start();
    
            //菜单状态置打开
            mFlag = true;
        }        
    

    唯一的难点就是根据第几个小图标,计算小图标的xy轴坐标了,注意三角函数Math.sin()的参数不是度数,而是弧度制的角度大小。

    • 退出动画其实和上面是相反的操作,参数前后换一下即可,但是考虑到是退出,所以应该时间短一点,变透明得快一点,且差值器就不用回弹效果了,可以用减速器的差值器(这样一开始可以速度快点),代码就不贴了。
    • 上面用到了一个工具类函数Utils.dip2px()转换dp参数为px值,如下:
    public static int dip2px(Context context, float dpValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale);
        }
    

    四、总结

    实现效果:

    menu.gif

    总的来说,属性动画可以快速方便地实现较为炫酷的效果,要自己多写几个经典的demo试试就行了。下一步可以学习更为厉害的VectorDrawable和贝塞尔曲线等等~~

    相关文章

      网友评论

      本文标题:Android开罐头———快速打造扇形卫星菜单

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