先看效果图
项目的总结构
下面开始贴代码,由于必要的地方都添加了注释,所以不过多讲解
anim_button.xml
- <?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
- <?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
- 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
- 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();
- }
- });
- }
- }
点击下载源码