创建扇形菜单步骤拆分
- 创建布局文件
- 我们以账本应用的收入、支出、转账三个功能为例子,分别创建三个对应的button
<ImageView android:id="@+id/btn_add" android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:padding="3dp" android:gravity="center" android:background="@drawable/round_button_shape" android:src="@drawable/icon_add" android:layout_alignParentRight="true" android:layout_above="@+id/nav_bottom" android:layout_marginRight="15dp" android:layout_marginBottom="15dp" android:textColor="@color/colorWhite" /> <Button android:id="@+id/btn_new_income" android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:padding="3dp" android:gravity="center" android:background="@drawable/round_button_shape" android:layout_alignParentRight="true" android:layout_above="@+id/nav_bottom" android:layout_marginRight="15dp" android:layout_marginBottom="15dp" android:textColor="@color/colorWhite" android:text="收入" android:alpha="0" android:visibility="gone" /> <Button android:id="@+id/btn_new_spending" android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:padding="3dp" android:gravity="center" android:background="@drawable/round_button_shape" android:layout_alignParentRight="true" android:layout_above="@+id/nav_bottom" android:layout_marginRight="15dp" android:layout_marginBottom="15dp" android:textColor="@color/colorWhite" android:alpha="0" android:visibility="gone" android:text="支出"/> <Button android:id="@+id/btn_new_transfer" android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:padding="3dp" android:gravity="center" android:background="@drawable/round_button_shape" android:layout_alignParentRight="true" android:layout_above="@+id/nav_bottom" android:layout_marginRight="15dp" android:layout_marginBottom="15dp" android:textColor="@color/colorWhite" android:text="转账" android:alpha="0" android:visibility="gone" />
- 我们以账本应用的收入、支出、转账三个功能为例子,分别创建三个对应的button
- 通过每个按钮的正弦和余弦确定其在扇形上的位置
double x = -Math.cos(0.5/(res.length-1)*(i-1)*Math.PI)* ScreenUtil.dip2px(this,dp); double y = -Math.sin(0.5/(res.length-1)*(i-1)*Math.PI)* ScreenUtil.dip2px(this,dp);
- 使用属性动画展示或收缩菜单
//展示扇形菜单 AnimatorSet set = new AnimatorSet(); set.playTogether( ObjectAnimator.ofFloat(btns.get(i-1),"translationX",(float)(x*0.25),(float)x), ObjectAnimator.ofFloat(btns.get(i-1),"translationY",(float)(y*0.25),(float)y) ,ObjectAnimator.ofFloat(btns.get(i-1),"alpha",0,1).setDuration(2000) );//透明度渐变 set.setInterpolator(new BounceInterpolator());//带有回弹效果的插值器 set.setDuration(2000); set.start() //加号 按钮旋转45° ObjectAnimator rotate=ObjectAnimator.ofFloat(btn_add,"rotation",0,45).setDuration(300); rotate.setInterpolator(new BounceInterpolator()); rotate.start(); //收缩扇形菜单 set.playTogether( ObjectAnimator.ofFloat(btns.get(i-1),"translationX",(float)x,(float)(x*0.25)), ObjectAnimator.ofFloat(btns.get(i-1),"translationY",(float)y,(float)(y*0.25)) ,ObjectAnimator.ofFloat(btns.get(i-1),"alpha",1,0).setDuration(2000) ); set.setInterpolator(new BounceInterpolator()); set.setDuration(2000); set.start(); //加号回归正位 ObjectAnimator rotate = ObjectAnimator.ofFloat(btn_add,"rotation",45,0).setDuration(300); rotate.setInterpolator(new BounceInterpolator()); rotate.start();
基本步骤就是这几步骤,下面给出展示菜单的完整代码
private boolean menuOpen=false;//是否展开菜单 private int[] res ={R.id.btn_new_income,R.id.btn_new_spending,R.id.btn_new_transfer};//定义三个按钮 private ArrayList<Button> btns = new ArrayList<Button>(); public void initView(){ for (int i = 0; i < res.length; i++) { Button btn = (Button)findViewById(res[i]); // btn.setOnClickListener(this); btns.add(btn); } } btn_add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(!menuOpen){ showAnim(100); }else { exitAnim(100); } } }); private void showAnim(int dp) { btn_new_income.setVisibility(View.VISIBLE); btn_new_spending.setVisibility(View.VISIBLE); btn_new_transfer.setVisibility(View.VISIBLE); AnimatorSet set = new AnimatorSet(); for (int i = 1; i <= res.length; i++) { // btns.get(i).setVisibility(View.VISIBLE); double x = -Math.cos(0.5/(res.length-1)*(i-1)*Math.PI)* ScreenUtil.dip2px(this,dp); double y = -Math.sin(0.5/(res.length-1)*(i-1)*Math.PI)* ScreenUtil.dip2px(this,dp); set.playTogether( ObjectAnimator.ofFloat(btns.get(i-1),"translationX",(float)(x*0.25),(float)x), ObjectAnimator.ofFloat(btns.get(i-1),"translationY",(float)(y*0.25),(float)y) ,ObjectAnimator.ofFloat(btns.get(i-1),"alpha",0,1).setDuration(2000) ); set.setInterpolator(new BounceInterpolator()); set.setDuration(2000); } set.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { menuOpen=true; } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); set.start(); ObjectAnimator rotate = ObjectAnimator.ofFloat(btn_add,"rotation",0,45).setDuration(300); rotate.setInterpolator(new BounceInterpolator()); rotate.start(); }