Android 動(dòng)態(tài)菜單實(shí)現(xiàn)實(shí)例代碼
Android 動(dòng)態(tài)菜單
先上效果圖
比較簡(jiǎn)單,主要就是屬性動(dòng)畫(huà)的使用和坐標(biāo)角度的小細(xì)節(jié)。
實(shí)現(xiàn)
實(shí)現(xiàn)效果:
圖標(biāo)按照路徑一路縮放漸變過(guò)來(lái)即可。
核心代碼
/** * Item開(kāi)啟動(dòng)畫(huà) * * @param btnItem * @param index * @param total * @param radius */ private void btnItemStartAnimator(View btnItem, int index, int total, int radius) { if (btnItem.getVisibility() != View.VISIBLE) { btnItem.setVisibility(View.VISIBLE); } double degree = Math.toRadians(90) / (total - 1) * index;//Math中根據(jù)度數(shù)得到弧度值的函數(shù) int translationX = -(int) (radius * Math.sin(degree)); int translationY = -(int) (radius * Math.cos(degree)); AnimatorSet set = new AnimatorSet(); //實(shí)現(xiàn)平移縮放和透明動(dòng)畫(huà) set.playTogether( ObjectAnimator.ofFloat(btnItem, "translationX", 0, translationX), ObjectAnimator.ofFloat(btnItem, "translationY", 0, translationY), ObjectAnimator.ofFloat(btnItem, "scaleX", 0, 1), ObjectAnimator.ofFloat(btnItem, "scaleY", 0, 1), ObjectAnimator.ofFloat(btnItem, "alpha", 0, 1) ); set.setInterpolator(new BounceInterpolator()); set.setDuration(500).start(); } /** * Item關(guān)閉動(dòng)畫(huà) * * @param btnItem * @param index * @param total * @param radius */ private void btnItemCloseAnimator(View btnItem, int index, int total, int radius) { double degree = Math.PI * index / ((total - 1) * 2); int translationX = -(int) (radius * Math.sin(degree)); int translationY = -(int) (radius * Math.cos(degree)); AnimatorSet set = new AnimatorSet(); //包含平移、縮放和透明度動(dòng)畫(huà) set.playTogether( ObjectAnimator.ofFloat(btnItem, "translationX", translationX, 0), ObjectAnimator.ofFloat(btnItem, "translationY", translationY, 0), ObjectAnimator.ofFloat(btnItem, "scaleX", 1f, 0f), ObjectAnimator.ofFloat(btnItem, "scaleY", 1f, 0f), ObjectAnimator.ofFloat(btnItem, "alpha", 1f, 0f)); set.setDuration(500).start(); if (btnItem.getVisibility() == View.VISIBLE) { btnItem.setVisibility(View.INVISIBLE); } }
item開(kāi)啟動(dòng)畫(huà)和關(guān)閉動(dòng)畫(huà)為一個(gè)逆過(guò)程,體現(xiàn)在x,y距離變化上。
x,y的距離開(kāi)啟時(shí)距離逐漸增長(zhǎng)
ObjectAnimator.ofFloat(btnItem, "translationX", 0, translationX), ObjectAnimator.ofFloat(btnItem, "translationY", 0, translationY),
這里要注意下sin這些弧度的計(jì)算,可以使用Math.toRadins(數(shù)字)
double degree = Math.toRadians(90) / (total - 1) * index;//Math中根據(jù)度數(shù)得到弧度值的函數(shù) int translationX = -(int) (radius * Math.sin(degree));
或者使用PI=180°來(lái)折算
double degree = Math.PI * index / ((total - 1) * 2); int translationX = -(int) (radius * Math.sin(degree));
實(shí)例代碼:
package xsf.customView; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.view.View; import android.view.animation.BounceInterpolator; import android.widget.Button; import android.widget.Toast; import xsf.customView.base.BaseActvity; public class StatelliteActivity extends BaseActvity { private Button btnMenu, btnItem1, btnItem2, btnItem3, btnItem4, btnItem5; private boolean isMenuOpen = false; @Override protected int setLayoutResourceId() { return R.layout.activity_statellite; } @Override protected void initView() { btnMenu = (Button) findViewById(R.id.btnMenu); btnMenu.setOnClickListener(this); btnItem1 = (Button) findViewById(R.id.btnItem1); btnItem1.setOnClickListener(this); btnItem2 = (Button) findViewById(R.id.btnItem2); btnItem2.setOnClickListener(this); btnItem3 = (Button) findViewById(R.id.btnItem3); btnItem3.setOnClickListener(this); btnItem4 = (Button) findViewById(R.id.btnItem4); btnItem4.setOnClickListener(this); btnItem5 = (Button) findViewById(R.id.btnItem5); btnItem5.setOnClickListener(this); } @Override public void onClick(View v) { btnMenu.requestFocus(); switch (v.getId()) { case R.id.btnMenu: showItemAnimator(); break; case R.id.btnItem1: Toast.makeText(StatelliteActivity.this, "點(diǎn)擊了Item1", Toast.LENGTH_SHORT).show(); break; case R.id.btnItem2: Toast.makeText(StatelliteActivity.this, "點(diǎn)擊了Item2", Toast.LENGTH_SHORT).show(); break; case R.id.btnItem3: Toast.makeText(StatelliteActivity.this, "點(diǎn)擊了Item3", Toast.LENGTH_SHORT).show(); break; case R.id.btnItem4: Toast.makeText(StatelliteActivity.this, "點(diǎn)擊了Item4", Toast.LENGTH_SHORT).show(); break; case R.id.btnItem5: Toast.makeText(StatelliteActivity.this, "點(diǎn)擊了Item5", Toast.LENGTH_SHORT).show(); break; } } private void showItemAnimator() { if (!isMenuOpen) { //此時(shí)menu是關(guān)閉的 isMenuOpen = true; btnItemStartAnimator(btnItem1, 0, 5, 300); btnItemStartAnimator(btnItem2, 1, 5, 300); btnItemStartAnimator(btnItem3, 2, 5, 300); btnItemStartAnimator(btnItem4, 3, 5, 300); btnItemStartAnimator(btnItem5, 4, 5, 300); } else { //此時(shí)menu是打開(kāi)的 isMenuOpen = false; btnItemCloseAnimator(btnItem1, 0, 5, 300); btnItemCloseAnimator(btnItem2, 1, 5, 300); btnItemCloseAnimator(btnItem3, 2, 5, 300); btnItemCloseAnimator(btnItem4, 3, 5, 300); btnItemCloseAnimator(btnItem5, 4, 5, 300); } } /** * 關(guān)閉動(dòng)畫(huà) * * @param btnItem * @param index * @param total * @param radius */ private void btnItemCloseAnimator(View btnItem, int index, int total, int radius) { double degree = Math.PI * index / ((total - 1) * 2); int translationX = -(int) (radius * Math.sin(degree)); int translationY = -(int) (radius * Math.cos(degree)); AnimatorSet set = new AnimatorSet(); //包含平移、縮放和透明度動(dòng)畫(huà) set.playTogether( ObjectAnimator.ofFloat(btnItem, "translationX", translationX, 0), ObjectAnimator.ofFloat(btnItem, "translationY", translationY, 0), ObjectAnimator.ofFloat(btnItem, "scaleX", 1f, 0f), ObjectAnimator.ofFloat(btnItem, "scaleY", 1f, 0f), ObjectAnimator.ofFloat(btnItem, "alpha", 1f, 0f)); set.setDuration(500).start(); if (btnItem.getVisibility() == View.VISIBLE) { btnItem.setVisibility(View.INVISIBLE); } } /** * 開(kāi)啟動(dòng)畫(huà) * * @param btnItem * @param index * @param total * @param radius */ private void btnItemStartAnimator(View btnItem, int index, int total, int radius) { if (btnItem.getVisibility() != View.VISIBLE) { btnItem.setVisibility(View.VISIBLE); } double degree = Math.toRadians(90) / (total - 1) * index;//Math中根據(jù)度數(shù)得到弧度值的函數(shù) int translationX = -(int) (radius * Math.sin(degree)); int translationY = -(int) (radius * Math.cos(degree)); AnimatorSet set = new AnimatorSet(); //實(shí)現(xiàn)平移縮放和透明動(dòng)畫(huà) set.playTogether( ObjectAnimator.ofFloat(btnItem, "translationX", 0, translationX), ObjectAnimator.ofFloat(btnItem, "translationY", 0, translationY), ObjectAnimator.ofFloat(btnItem, "scaleX", 0, 1), ObjectAnimator.ofFloat(btnItem, "scaleY", 0, 1), ObjectAnimator.ofFloat(btnItem, "alpha", 0, 1) ); set.setInterpolator(new BounceInterpolator()); set.setDuration(500).start(); } }
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- Android左右滑出菜單實(shí)例分析
- android底部菜單欄實(shí)現(xiàn)原理與代碼
- android popwindow實(shí)現(xiàn)左側(cè)彈出菜單層及PopupWindow主要方法介紹
- Android ListView長(zhǎng)按彈出菜單二種實(shí)現(xiàn)方式示例
- Android開(kāi)發(fā)技巧之我的菜單我做主(自定義菜單)
- Android仿QQ空間底部菜單示例代碼
- Android界面設(shè)計(jì)(APP設(shè)計(jì)趨勢(shì) 左側(cè)隱藏菜單右邊顯示content)
- 基于Android實(shí)現(xiàn)點(diǎn)擊某個(gè)按鈕讓菜單選項(xiàng)從按鈕周圍指定位置彈出
- Android之用PopupWindow實(shí)現(xiàn)彈出菜單的方法詳解
- Android仿UC底部菜單欄實(shí)現(xiàn)原理與代碼
相關(guān)文章
Android開(kāi)發(fā)ProGuard使用技巧掌握
這篇文章主要為大家介紹了Android開(kāi)發(fā)ProGuard使用技巧的掌握,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Android開(kāi)發(fā)技巧之在a標(biāo)簽或TextView控件中單擊鏈接彈出Activity(自定義動(dòng)作)
a標(biāo)簽以及TextView自動(dòng)識(shí)別的特殊文本(網(wǎng)址、電話號(hào)、Email等),這些都可以通過(guò)單擊來(lái)觸發(fā)不同的動(dòng)作;但如果讀者想在單擊鏈接時(shí)執(zhí)行任意自定義的動(dòng)作,那么將要介紹的一定是你想要的了2013-01-01Android使用動(dòng)畫(huà)設(shè)置ProgressBar進(jìn)度的方法
這篇文章主要為大家詳細(xì)介紹了Android使用動(dòng)畫(huà)設(shè)置ProgressBar進(jìn)度的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01android遞歸壓縮上傳多張圖片到七牛的實(shí)例代碼
本篇文章主要介紹了android遞歸壓縮上傳多張圖片到七牛的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Android中使用LayoutInflater要注意的一些坑
LayoutInflater類在我們?nèi)粘i_(kāi)發(fā)中經(jīng)常會(huì)用到,最近在使用中就遇到了一些問(wèn)題,所有下面這篇文章主要給大家總結(jié)了關(guān)于Android中使用LayoutInflater要注意的一些坑,希望通過(guò)這篇能讓大家避免走一些彎路,需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看吧。2017-04-04Android身份證號(hào)有效性校驗(yàn)工具類案例
這篇文章主要介紹了Android身份證號(hào)有效性校驗(yàn)工具類案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09Android開(kāi)發(fā)使用UncaughtExceptionHandler捕獲全局異常
本文主要介紹在Android開(kāi)發(fā)中使用UncaughtExceptionHandler捕獲全局異常,需要的朋友可以參考下。2016-06-06flutter 路由機(jī)制的實(shí)現(xiàn)
本文主要介紹 flutter 中的路由實(shí)現(xiàn)原理,包括初始化時(shí)的頁(yè)面加載、切換頁(yè)面的底層機(jī)制等。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07