时间:2021-01-29 09:34:32 | 栏目:Android代码 | 点击:次
本文介绍利用ObjectAnimator简单地实现ArcMenu,直接使用本文的ArcMenu类即可快捷地实现菜单功能。
最终使用效果:
先看下最终的使用效果:
private int[] imageRes = {R.id.img_menu, R.id.img_menu1, R.id.img_menu2, R.id.img_menu3, R.id.img_menu4, R.id.img_menu5}; private ArcMenu arcMenu; ... //初始化,参数为资源图片id arcMenu = new ArcMenu(this, imageRes); //点击事件,这边使用了annotation,直接使用findViewById然后设置监听事件也可以 @Click public void img_menu() { mylog.d(" @Click img_menu"); arcMenu.switchMenu(); } @Click public void img_menu1() { arcMenu.clickItem(); mylog.d(" @Click img_menu1"); } @Click public void img_menu2() { arcMenu.clickItem(); mylog.d(" @Click img_menu2"); } @Click public void img_menu3() { arcMenu.clickItem(); mylog.d(" @Click img_menu3"); } @Click public void img_menu4() { arcMenu.clickItem(); mylog.d(" @Click img_menu4"); } @Click public void img_menu5() { arcMenu.clickItem(); mylog.d(" @Click img_menu5"); }
布局文件中,将需要用到的图片放在同一位置。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/widget33" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#262a34"> <ImageView android:id="@+id/img_menu" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:src="@drawable/menu_add" /> <ImageView android:id="@+id/img_menu1" android:visibility="gone" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:src="@drawable/float_on" /> <ImageView android:id="@+id/img_menu2" android:visibility="gone" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:src="@drawable/float_on" /> <ImageView android:id="@+id/img_menu3" android:visibility="gone" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:src="@drawable/float_on" /> <ImageView android:id="@+id/img_menu4" android:visibility="gone" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:src="@drawable/float_on" /> <ImageView android:id="@+id/img_menu5" android:visibility="gone" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:src="@drawable/float_on" /> </RelativeLayout>
下面为截图;
具体实现
初始化,通过imageRes的数量设置相邻两个图标之间的角度,同时将imageView加入imageViewList中,方便后面使用
public class ArcMenu { private Activity context; private int[] imageRes; private List<ImageView> imageViewList = new ArrayList<>(); private boolean isShowMenu = false; int radius = 180; double angle; public ArcMenu(Activity context, int[] imageRes) { angle = Math.PI / 2 / (imageRes.length - 2); radius = Tool.dip2px(context, radius); this.context = context; this.imageRes = imageRes; for (int imagRe : imageRes) { ImageView imageView = (ImageView) context.findViewById(imagRe); imageViewList.add(imageView); } } }
菜单弹出动画,使用ObjectAnimator,对每一个图标进行平移操作,第0个图标为菜单开关,加入旋转动画。
private void openMenu() { isShowMenu = true; setItemVisible(true); ObjectAnimator animator1; ObjectAnimator animator2; List<ObjectAnimator> objectAnimators = new ArrayList<>(); AnimatorSet set = new AnimatorSet(); for (int i = 1; i < imageRes.length; i++) { animator1 = ObjectAnimator.ofFloat(imageViewList.get(i), "translationX", (float) (-radius * Math.sin(angle * (i-1)))); animator2 = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", (float) (-radius * Math.cos(angle * (i-1)))); objectAnimators.add(animator1); objectAnimators.add(animator2); } for (int i = 0; i < objectAnimators.size(); i++) { set.playTogether(objectAnimators.get(i)); } set.setDuration(200); set.start(); //第0个图标,菜单图标,加入动画 ObjectAnimator.ofFloat(imageViewList.get(0),"rotation",0,135f).setDuration(200).start(); }
同理,关闭菜单
private void closeMenu() { isShowMenu = false; ObjectAnimator animator1 = null; ObjectAnimator animator2; List<ObjectAnimator> objectAnimators = new ArrayList<>(); AnimatorSet set = new AnimatorSet(); for (int i = 1; i < imageRes.length; i++) { animator1 = ObjectAnimator.ofFloat(imageViewList.get(i), "translationX", 0); animator2 = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 0); objectAnimators.add(animator1); objectAnimators.add(animator2); } animator1.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { setItemVisible(false); super.onAnimationEnd(animation); } }); for (int i = 0; i < objectAnimators.size(); i++) { set.playTogether(objectAnimators.get(i)); } set.setDuration(200); set.start(); ObjectAnimator.ofFloat(imageViewList.get(0),"rotation",135f,0).setDuration(200).start(); }
切换菜单开关
public void switchMenu() { if (isShowMenu) { closeMenu(); } else { openMenu(); } }
图标被点击后,将所有子图标隐藏,同时调用closMenu(),将图片移回原处。
public void clickItem() { setItemVisible(false); closeMenu(); } private void setItemVisible(boolean isVisible) { for (int i = 1; i < imageRes.length; i++) { if (isVisible) { imageViewList.get(i).setVisibility(View.VISIBLE); } else { imageViewList.get(i).setVisibility(View.GONE); } } }
至此,整个功能大致完成。现有的功能默认arcmenu为界面右下角,其他位置相应地修改公式即可以实现,可自行进行拓展,兼容不同位置。