美文网首页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