1. 程式人生 > >Android 實現爆炸式選單按鈕彈出效果

Android 實現爆炸式選單按鈕彈出效果

最近專案要使用到點選一個按鈕彈出多個按鈕的效果,在試了幾個類庫後感覺不是很理想,所以自己程式碼實現了一個,下圖所示:

這裡寫圖片描述

實現原理很簡單,就是利用android原聲動畫效果,當點選中心按鈕時彈出其餘按鈕。閒話少敘,程式碼如下。
第一步:activity_main.xml 很簡單,也就是五個相同位置的按鈕

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width
="match_parent" android:layout_height="match_parent" >
<ImageButton android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_margin="10dp" android:src
="@drawable/im" android:background="@android:color/transparent"/>
<ImageButton android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_margin="10dp" android:visibility
="invisible" android:src="@drawable/i" android:background="@android:color/transparent"/>
<ImageButton android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_margin="10dp" android:src="@drawable/ii" android:visibility="invisible" android:background="@android:color/transparent"/> <ImageButton android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_margin="10dp" android:src="@drawable/iii" android:visibility="invisible" android:background="@android:color/transparent"/> <ImageButton android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_margin="10dp" android:src="@drawable/iiii" android:visibility="invisible" android:background="@android:color/transparent" /> </RelativeLayout>

第二步:MainActivity

package com.example.boombuttons;

import java.util.ArrayList;

public class MainActivity extends Activity implements OnClickListener{
    // 中心按鈕
    private ImageButton button;

    // 四個子按鈕
    private ImageButton button1;
    private ImageButton button2;    
    private ImageButton button3;    
    private ImageButton button4;

    // 子按鈕列表
    private List<ImageButton> buttonItems = new ArrayList<ImageButton>(3);

    // 標識當前按鈕彈出與否,1代表已經未彈出,-1代表已彈出
    private int flag = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 例項化按鈕並設立監聽
        button  = (ImageButton)findViewById(R.id.button);
        button.setOnClickListener(this);
        button1 = (ImageButton)findViewById(R.id.button1);
        button2 = (ImageButton)findViewById(R.id.button2);
        button3 = (ImageButton)findViewById(R.id.button3);
        button4 = (ImageButton)findViewById(R.id.button4);

        // 將子按鈕們加入列表中
        buttonItems.add(button1);
        buttonItems.add(button2);
        buttonItems.add(button3);
        buttonItems.add(button4);   
    }

    /**
     * 按鈕移動動畫
     * @params 子按鈕列表
     * @params 彈出時圓形半徑radius
     */
    public void buttonAnimation(List<ImageButton> buttonList,int radius){

        for(int i=0;i<buttonList.size();i++){

            ObjectAnimator objAnimatorX;
            ObjectAnimator objAnimatorY;
            ObjectAnimator objAnimatorRotate;

            // 將按鈕設為可見
            buttonList.get(i).setVisibility(View.VISIBLE);

            // 按鈕在X、Y方向的移動距離
            float distanceX = (float) (flag*radius*(Math.cos(Util.getAngle(buttonList.size(),i))));
            float distanceY = -(float) (flag*radius*(Math.sin(Util.getAngle(buttonList.size(),i))));

            // X方向移動
            objAnimatorX = ObjectAnimator.ofFloat(buttonList.get(i), "x", buttonList.get(i).getX(),buttonList.get(i).getX()+distanceX);
            objAnimatorX.setDuration(200);
            objAnimatorX.setStartDelay(100);
            objAnimatorX.start();

            // Y方向移動
            objAnimatorY = ObjectAnimator.ofFloat(buttonList.get(i), "y", buttonList.get(i).getY(),buttonList.get(i).getY()+distanceY);
            objAnimatorY.setDuration(200);
            objAnimatorY.setStartDelay(100);
            objAnimatorY.start();

            // 按鈕旋轉
            objAnimatorRotate = ObjectAnimator.ofFloat(buttonList.get(i), "rotation", 0, 360);
            objAnimatorRotate.setDuration(200);
            objAnimatorY.setStartDelay(100);
            objAnimatorRotate.start();

            if(flag==-1){
                objAnimatorX.addListener(new AnimatorListener() {

                    @Override
                    public void onAnimationStart(Animator animation) {
                        // TODO Auto-generated method stub
                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {
                        // TODO Auto-generated method stub
                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        // TODO Auto-generated method stub
                        // 將按鈕設為可見
                        for (int i = 0; i < buttonItems.size(); i++) {
                            buttonItems.get(i).setVisibility(View.INVISIBLE);
                        }
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                        // TODO Auto-generated method stub
                    }
                });
            }

        }
    }

}

第三步:Util.java 工具類,寫了一個靜態方法,用於通過按鈕個數和按鈕在列表中的索引計算其彈出角度。

public class Util {

    /**
     * 返回每個按鈕應該出現的角度(弧度單位)
     * @param index
     * @return double 角度(弧度單位)
     */
    public static double getAngle(int total,int index){

        return Math.toRadians(90/(total-1)*index+90);
    }
}

好了,真麻痺累,轉載請標明地址,謝!