Android利用ObjectAnimator实现ArcMenu
内容摘要
本文介绍利用ObjectAnimator简单地实现ArcMenu,直接使用本文的ArcMenu类即可快捷地实现菜单功能。
最终使用效果:
先看下最终的使用效果:
private int[] imageRes = {R
最终使用效果:
先看下最终的使用效果:
private int[] imageRes = {R
文章正文
本文介绍利用ObjectAnimator简单地实现ArcMenu,直接使用本文的ArcMenu类即可快捷地实现菜单功能。
最终使用效果:
先看下最终的使用效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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" ); } |
布局文件中,将需要用到的图片放在同一位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | <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中,方便后面使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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个图标为菜单开关,加入旋转动画。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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(); } |
同理,关闭菜单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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(); } |
切换菜单开关
1 2 3 4 5 6 7 | public void switchMenu() { if (isShowMenu) { closeMenu(); } else { openMenu(); } } |
图标被点击后,将所有子图标隐藏,同时调用closMenu(),将图片移回原处。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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为界面右下角,其他位置相应地修改公式即可以实现,可自行进行拓展,兼容不同位置。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持phpstudy。
代码注释