您的位置:首页 > 移动开发 > Android开发

【Android界面实现】实现底部扇形展开菜单效果

2016-07-27 22:01 603 查看
http://blog.csdn.net/zhaokaiqiang1992/article/details/20998313

版权声明:本文为博主原创文章,未经博主允许不得转载。

先看效果图





项目的总结构



下面开始贴代码,由于必要的地方都添加了注释,所以不过多讲解

anim_button.xml

[html]
view plain
copy





<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" >  
  
    <Button  
        android:id="@+id/btn_sleep"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_alignParentBottom="true"  
        android:layout_alignParentLeft="true"  
        android:layout_marginBottom="10dp"  
        android:layout_marginLeft="10dp"  
        android:visibility="invisible"  
        android:background="@drawable/composer_sleep" />  
  
    <Button  
        android:id="@+id/btn_thought"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_alignParentBottom="true"  
        android:layout_alignParentLeft="true"  
        android:layout_marginBottom="10dp"  
        android:layout_marginLeft="10dp"  
        android:visibility="invisible"  
        android:background="@drawable/composer_thought" />  
  
    <Button  
        android:id="@+id/btn_music"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_alignParentBottom="true"  
        android:layout_alignParentLeft="true"  
        android:layout_marginBottom="10dp"  
        android:layout_marginLeft="10dp"  
        android:visibility="invisible"  
        android:background="@drawable/composer_music" />  
  
    <Button  
        android:id="@+id/btn_place"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_alignParentBottom="true"  
        android:layout_alignParentLeft="true"  
        android:layout_marginBottom="10dp"  
        android:layout_marginLeft="10dp"  
        android:visibility="invisible"  
        android:background="@drawable/composer_place" />  
  
    <Button  
        android:id="@+id/btn_with"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_alignParentBottom="true"  
        android:layout_alignParentLeft="true"  
        android:layout_marginBottom="10dp"  
        android:layout_marginLeft="10dp"  
        android:visibility="invisible"  
        android:background="@drawable/composer_with" />  
  
    <Button  
        android:id="@+id/btn_camera"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_alignParentBottom="true"  
        android:layout_alignParentLeft="true"  
        android:layout_marginBottom="10dp"  
        android:layout_marginLeft="10dp"  
        android:visibility="invisible"  
        android:background="@drawable/composer_camera" />  
  
    <Button  
        android:id="@+id/btn_menu"  
        android:layout_width="60dp"  
        android:layout_height="60dp"  
        android:layout_alignParentBottom="true"  
        android:layout_alignParentLeft="true"  
        android:background="@drawable/friends_delete" />  
  
</RelativeLayout>  

主界面的布局main.xml

[html]
view plain
copy





<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical" >  
      
    <com.example.anim.AnimButtons  
        android:id="@+id/animButtons"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        />  
</LinearLayout>  

最重要的,自定义控件的实现
AnimButtons.java

[java]
view plain
copy





package com.example.anim;  
  
import android.R.anim;  
import android.content.Context;  
import android.util.AttributeSet;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.animation.Animation;  
import android.view.animation.Animation.AnimationListener;  
import android.view.animation.ScaleAnimation;  
import android.view.animation.TranslateAnimation;  
import android.widget.Button;  
import android.widget.RelativeLayout;  
  
/** 
 * 底部展开菜单实现 
 *  
 * @author ZhaoKaiQiang 
 *  
 *         Time:2014年3月11日 
 */  
public class AnimButtons extends RelativeLayout {  
  
    private Context context;  
    private int leftMargin = 0, bottomMargin = 0;  
    private final int buttonWidth = 58;// 图片宽高  
    private final int r = 180;// 半径  
    private final int maxTimeSpent = 200;// 最长动画耗时  
    private final int minTimeSpent = 80;// 最短动画耗时  
    private int intervalTimeSpent;// 每相邻2个的时间间隔  
    private Button[] btns;  
    private Button btn_menu;  
    private RelativeLayout.LayoutParams params;  
    private boolean isOpen = false;// 是否菜单打开状态  
    private float angle;// 每个按钮之间的夹角  
  
    public int bottomMargins = this.getMeasuredHeight() - buttonWidth  
            - bottomMargin;  
  
    public AnimButtons(Context context) {  
        super(context);  
        this.context = context;  
    }  
  
    public AnimButtons(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        this.context = context;  
    }  
  
    @Override  
    protected void onFinishInflate() {  
        super.onFinishInflate();  
        View view = LayoutInflater.from(context).inflate(R.layout.anim_buttons,  
                this);  
  
        initButtons(view);  
  
    }  
  
    private void initButtons(View view) {  
        // 可以根据按钮的个数自己增减  
        btns = new Button[4];  
        btns[0] = (Button) view.findViewById(R.id.btn_camera);  
        btns[1] = (Button) view.findViewById(R.id.btn_with);  
        btns[2] = (Button) view.findViewById(R.id.btn_place);  
        btns[3] = (Button) view.findViewById(R.id.btn_music);  
        // btns[4] = (Button) view.findViewById(R.id.btn_thought);  
        // btns[5] = (Button) view.findViewById(R.id.btn_sleep);  
        btn_menu = (Button) view.findViewById(R.id.btn_menu);  
  
        leftMargin = ((RelativeLayout.LayoutParams) (btn_menu.getLayoutParams())).leftMargin;  
        bottomMargin = ((RelativeLayout.LayoutParams) (btn_menu  
                .getLayoutParams())).bottomMargin;  
  
        for (int i = 0; i < btns.length; i++) {  
            // 初始化的时候按钮重合  
            btns[i].setLayoutParams(btn_menu.getLayoutParams());  
            btns[i].setTag(String.valueOf(i));  
            btns[i].setOnClickListener(clickListener);  
        }  
  
        intervalTimeSpent = (maxTimeSpent - minTimeSpent) / btns.length;  
        angle = (float) Math.PI / (2 * (btns.length - 1));  
    }  
  
    @Override  
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
        super.onSizeChanged(w, h, oldw, oldh);  
        bottomMargins = this.getMeasuredHeight() - buttonWidth - bottomMargin;  
        btn_menu.setOnClickListener(new OnClickListener() {  
  
            @Override  
            public void onClick(View v) {  
                if (!isOpen) {  
                    openMenu();  
                } else {  
                    closeMenu();  
                }  
            }  
        });  
  
    }  
  
    public void closeMenu() {  
        if (isOpen == true) {  
            isOpen = false;  
            for (int i = 0; i < btns.length; i++) {  
                float xLenth = (float) (r * Math.sin(i * angle));  
                float yLenth = (float) (r * Math.cos(i * angle));  
                btns[i].startAnimation(animTranslate(-xLenth, yLenth,  
                        leftMargin, bottomMargins, btns[i], maxTimeSpent - i  
                                * intervalTimeSpent));  
                btns[i].setVisibility(View.INVISIBLE);  
            }  
        }  
    }  
  
    public void openMenu() {  
        isOpen = true;  
        for (int i = 0; i < btns.length; i++) {  
            float xLenth = (float) (r * Math.sin(i * angle));  
            float yLenth = (float) (r * Math.cos(i * angle));  
            btns[i].startAnimation(animTranslate(xLenth, -yLenth, leftMargin  
                    + (int) xLenth, bottomMargins - (int) yLenth, btns[i],  
                    minTimeSpent + i * intervalTimeSpent));  
            btns[i].setVisibility(View.VISIBLE);  
        }  
  
    }  
  
    private Animation animScale(float toX, float toY) {  
        Animation animation = new ScaleAnimation(1.0f, toX, 1.0f, toY,  
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  
                0.5f);  
        animation.setInterpolator(context,  
                anim.accelerate_decelerate_interpolator);  
        animation.setDuration(400);  
        animation.setFillAfter(false);  
        return animation;  
  
    }  
  
    private Animation animTranslate(float toX, float toY, final int lastX,  
            final int lastY, final Button button, long durationMillis) {  
        Animation animation = new TranslateAnimation(0, toX, 0, toY);  
        animation.setAnimationListener(new AnimationListener() {  
  
            @Override  
            public void onAnimationStart(Animation animation) {  
  
            }  
  
            @Override  
            public void onAnimationRepeat(Animation animation) {  
  
            }  
  
            @Override  
            public void onAnimationEnd(Animation animation) {  
                params = new RelativeLayout.LayoutParams(0, 0);  
                params.height = buttonWidth;  
                params.width = buttonWidth;  
                params.setMargins(lastX, lastY, 0, 0);  
                button.setLayoutParams(params);  
                button.clearAnimation();  
  
            }  
        });  
        animation.setDuration(durationMillis);  
        return animation;  
    }  
  
    View.OnClickListener clickListener = new View.OnClickListener() {  
  
        @Override  
        public void onClick(View v) {  
            int selectedItem = Integer.parseInt((String) v.getTag());  
            for (int i = 0; i < btns.length; i++) {  
                if (i == selectedItem) {  
                    btns[i].startAnimation(animScale(2.0f, 2.0f));  
                } else {  
                    btns[i].startAnimation(animScale(0.0f, 0.0f));  
                }  
            }  
            if (onButtonClickListener != null) {  
                onButtonClickListener.onButtonClick(v, selectedItem);  
            }  
        }  
  
    };  
  
    public boolean isOpen() {  
        return isOpen;  
    }  
  
    private OnButtonClickListener onButtonClickListener;  
  
    public interface OnButtonClickListener {  
        void onButtonClick(View v, int id);  
    }  
  
    public void setOnButtonClickListener(  
            OnButtonClickListener onButtonClickListener) {  
        this.onButtonClickListener = onButtonClickListener;  
    }  
  
}  

AnimButtonsActivity.java

[java]
view plain
copy





package com.example.anim;  
  
import android.app.Activity;  
import android.os.Bundle;  
import android.view.View;  
import android.widget.Toast;  
/** 
 * 主界面 
 * @author  ZhaoKaiQiang 
 *           
 *          Time:2014年3月11日 
 */  
public class AnimButtonsActivity extends Activity {  
  
    private AnimButtons animButtons;  
      
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        animButtons = (AnimButtons) findViewById(R.id.animButtons);  
        animButtons  
                .setOnButtonClickListener(new AnimButtons.OnButtonClickListener() {  
                    @Override  
                    public void onButtonClick(View v, int id) {  
                        Toast.makeText(AnimButtonsActivity.this, "id-->" + id,  
                                0).show();  
                        animButtons.closeMenu();  
                    }  
                });  
    }  
}  

点击下载源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: