Android開發中利用ObjectAnimator實現ArcMenu
本文由碼農網 – 蘇耀東原創,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
本文介紹利用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為介面右下角,其他位置相應地修改公式即可以實現,可自行進行擴充,相容不同位置。
本文連結:http://www.codeceo.com/article/android-objectanimator-arcmenu.html
本文作者:碼農網 – 蘇耀東
[ 原創作品,轉載必須在正文中標註並保留原文連結和作者等資訊。]
相關文章
- Android開發中陰影效果的實現Android
- Android開發利用NanoHttpd搭建伺服器AndroidNaNhttpd伺服器
- 現有Android專案中整合Flutter/Flutter混合開發實戰(一)AndroidFlutter
- Android開發中API層的最佳實踐AndroidAPI
- Android開發 - (介面卡)Adapter類中BaseAdapter實現類詳細解析AndroidAPT
- Android開發 - (介面卡)Adapter類中SimpleAdapter實現類詳細解析AndroidAPT
- Android小知識-利用OkHttp實現WebSocket通訊AndroidHTTPWeb
- 利用 Android 系統原生 API 實現分享功能(2)AndroidAPI
- [譯] 如何在 Android 開發中充分利用多攝像頭 APIAndroidAPI
- android 利用path 實現手寫板的手寫效果Android
- Android開發_在Android Studio中搜尋專案中出現過的字串Android字串
- Android Studio中NDK開發Android
- 利用自定義流程表單開發的優勢,實現流程化發展!
- 創業中如何實現敏捷開發創業敏捷
- android開發(3):列表listview的實現 | 下拉重新整理AndroidView
- android開發透過wireshark實現flutter應用抓包AndroidFlutter
- Android實際開發中實用的第三方(開源)框架Android框架
- 現有Android專案中整合Flutter/Flutter混合開發實戰(二):FlutterActivity原始碼分析AndroidFlutter原始碼
- Android開發:在Eclipse中配置Android環境AndroidEclipse
- Flutter、Android混合開發實踐FlutterAndroid
- Android 開發中的SSL pinningAndroid
- Android中SharePreferences的簡單實現Android
- android短影片開發,點選兩次實現不同點選效果的實現方式Android
- Android 實現開機自啟APPAndroidAPP
- 利用tensorflow.js實現JS中的AIJSAI
- Linux中利用NFS實現飛鴿傳書LinuxNFS
- 利用Redis實現高併發計數器Redis
- 從Android到ReactNative開發(二、通訊與模組實現)AndroidReact
- 容器中的容器——利用Dind實現開箱即用的K3s
- 利用 Vagrant 實現 Laravel 多個開發環境 (Ubuntu 18.4、Ubuntu 16.4) (with Bug)Laravel開發環境Ubuntu
- flutter 混合開發 (android 實際操作)FlutterAndroid
- Android 開發實用程式碼收集Android
- Android藍芽開發流程實踐Android藍芽
- Android模組化開發實踐Android
- android中foreground水波實現過程分析Android
- React Native在Android當中實踐(二)——搭建開發環境React NativeAndroid開發環境
- android canvas.drawBitmap(bitmap, matrix, paint) 中 利用 matrix 實現平移到中心點及中心點縮放AndroidCanvasAI
- PostgreSQL中利用驅動程式實現故障轉移SQL