仿的一个动画菜单效果

http://gundumw100.iteye.com/blog/1299953

记得在eoe上有人发过,但代码质量不好。我重写了一下,抽成了控件。但没有经过各种控件的相容性测试,如果和其他控件的相容性不好,就直接在activity中写代码吧,应该差不多的。
我用的是平板,所以效果还行,不知道手机如何。




代码:

Java代码 复制代码 收藏代码
  1. package com.ql.view;
  2. import android.R.anim;
  3. import android.content.Context;
  4. import android.util.AttributeSet;
  5. import android.util.Log;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.view.animation.Animation;
  9. import android.view.animation.RotateAnimation;
  10. import android.view.animation.ScaleAnimation;
  11. import android.view.animation.TranslateAnimation;
  12. import android.view.animation.Animation.AnimationListener;
  13. import android.widget.Button;
  14. import android.widget.RelativeLayout;
  15. import com.ql.app.R;
  16. public class AnimButtons extends RelativeLayout{
  17. private Context context;
  18. private int leftMargin=0,bottomMargin=0;
  19. private final int buttonWidth=58;//图片宽高
  20. private final int r=180;//半径
  21. private final int maxTimeSpent=200;//最长动画耗时
  22. private final int minTimeSpent=80;//最短动画耗时
  23. private int intervalTimeSpent;//每相邻2个的时间间隔
  24. private Button[] btns;
  25. private Button btn_menu;
  26. private RelativeLayout.LayoutParams params;
  27. private boolean isOpen = false;//是否菜单打开状态
  28. private float angle;//每个按钮之间的夹角
  29. public AnimButtons(Context context) {
  30. super(context);
  31. // TODO Auto-generated constructor stub
  32. this.context=context;
  33. }
  34. public AnimButtons(Context context, AttributeSet attrs) {
  35. super(context, attrs);
  36. // TODO Auto-generated constructor stub
  37. this.context=context;
  38. }
  39. @Override
  40. protected void onFinishInflate() {
  41. // TODO Auto-generated method stub
  42. super.onFinishInflate();
  43. View view=LayoutInflater.from(context).inflate(R.layout.anim_buttons, this);
  44. initButtons(view);
  45. }
  46. private void initButtons(View view){
  47. // TODO Auto-generated method stub
  48. //6个按钮,具体视情况而定
  49. btns=new Button[6];
  50. btns[0] = (Button) view.findViewById(R.id.btn_camera);
  51. btns[1] = (Button) view.findViewById(R.id.btn_with);
  52. btns[2] = (Button) view.findViewById(R.id.btn_place);
  53. btns[3] = (Button) view.findViewById(R.id.btn_music);
  54. btns[4] = (Button) view.findViewById(R.id.btn_thought);
  55. btns[5] = (Button) view.findViewById(R.id.btn_sleep);
  56. btn_menu = (Button) view.findViewById(R.id.btn_menu);
  57. leftMargin=((RelativeLayout.LayoutParams)(btn_menu.getLayoutParams())).leftMargin;
  58. bottomMargin=((RelativeLayout.LayoutParams)(btn_menu.getLayoutParams())).bottomMargin;
  59. for(int i=0;i<btns.length;i++){
  60. btns[i].setLayoutParams(btn_menu.getLayoutParams());//初始化的时候按钮都重合
  61. btns[i].setTag(String.valueOf(i));
  62. btns[i].setOnClickListener(clickListener);
  63. }
  64. intervalTimeSpent=(maxTimeSpent-minTimeSpent)/btns.length;//20
  65. angle=(float)Math.PI/(2*(btns.length-1));
  66. }
  67. @Override
  68. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  69. // TODO Auto-generated method stub
  70. super.onSizeChanged(w, h, oldw, oldh);
  71. final int bottomMargins=this.getMeasuredHeight()-buttonWidth-bottomMargin;
  72. // Log.i("tag", "bottomMargins====="+bottomMargins);
  73. btn_menu.setOnClickListener(new OnClickListener() {
  74. @Override
  75. public void onClick(View v) {
  76. // TODO Auto-generated method stub
  77. if(!isOpen){
  78. isOpen = true;
  79. // btn_menu.startAnimation(animRotate(-45.0f, 0.5f, 0.45f));
  80. for(int i=0;i<btns.length;i++){
  81. float xLenth=(float)(r*Math.sin(i*angle));
  82. float yLenth=(float)(r*Math.cos(i*angle));
  83. // Log.i("tag", "xLenth======"+xLenth+",yLenth======"+yLenth);
  84. btns[i].startAnimation(animTranslate(xLenth, -yLenth, leftMargin+(int)xLenth, bottomMargins - (int)yLenth, btns[i], minTimeSpent+i*intervalTimeSpent));
  85. }
  86. }
  87. else{
  88. isOpen = false;
  89. // btn_menu.startAnimation(animRotate(90.0f, 0.5f, 0.45f));
  90. for(int i=0;i<btns.length;i++){
  91. float xLenth=(float)(r*Math.sin(i*angle));
  92. float yLenth=(float)(r*Math.cos(i*angle));
  93. // Log.i("tag", "xLenth======"+xLenth+",yLenth======"+yLenth);
  94. btns[i].startAnimation(animTranslate(-xLenth, yLenth, leftMargin, bottomMargins, btns[i], maxTimeSpent-i*intervalTimeSpent));
  95. }
  96. }
  97. }
  98. });
  99. }
  100. private Animation animScale(float toX, float toY){
  101. // TODO Auto-generated method stub
  102. Animation animation = new ScaleAnimation(1.0f, toX, 1.0f, toY, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
  103. animation.setInterpolator(context, anim.accelerate_decelerate_interpolator);
  104. animation.setDuration(400);
  105. animation.setFillAfter(false);
  106. return animation;
  107. }
  108. private Animation animRotate(float toDegrees, float pivotXValue, float pivotYValue){
  109. // TODO Auto-generated method stub
  110. final Animation animation = new RotateAnimation(0, toDegrees, Animation.RELATIVE_TO_SELF, pivotXValue, Animation.RELATIVE_TO_SELF, pivotYValue);
  111. animation.setAnimationListener(new AnimationListener(){
  112. @Override
  113. public void onAnimationStart(Animation animation){
  114. // TODO Auto-generated method stub
  115. }
  116. @Override
  117. public void onAnimationRepeat(Animation animation){
  118. // TODO Auto-generated method stub
  119. }
  120. @Override
  121. public void onAnimationEnd(Animation animation){
  122. // TODO Auto-generated method stub
  123. animation.setFillAfter(true);
  124. }
  125. });
  126. return animation;
  127. }
  128. private Animation animTranslate(float toX, float toY, final int lastX, final int lastY,
  129. final Button button, long durationMillis){
  130. // TODO Auto-generated method stub
  131. Animation animation = new TranslateAnimation(0, toX, 0, toY);
  132. animation.setAnimationListener(new AnimationListener(){
  133. @Override
  134. public void onAnimationStart(Animation animation){
  135. // TODO Auto-generated method stub
  136. }
  137. @Override
  138. public void onAnimationRepeat(Animation animation) {
  139. // TODO Auto-generated method stub
  140. }
  141. @Override
  142. public void onAnimationEnd(Animation animation){
  143. // TODO Auto-generated method stub
  144. params = new RelativeLayout.LayoutParams(0, 0);
  145. params.height = buttonWidth;
  146. params.width = buttonWidth;
  147. params.setMargins(lastX, lastY, 0, 0);
  148. button.setLayoutParams(params);
  149. button.clearAnimation();
  150. }
  151. });
  152. animation.setDuration(durationMillis);
  153. return animation;
  154. }
  155. View.OnClickListener clickListener=new View.OnClickListener(){
  156. @Override
  157. public void onClick(View v) {
  158. // TODO Auto-generated method stub
  159. int selectedItem=Integer.parseInt((String)v.getTag());
  160. for(int i=0;i<btns.length;i++){
  161. if(i==selectedItem){
  162. btns[i].startAnimation(animScale(2.0f, 2.0f));
  163. }else{
  164. btns[i].startAnimation(animScale(0.0f, 0.0f));
  165. }
  166. }
  167. if(onButtonClickListener!=null){
  168. onButtonClickListener.onButtonClick(v, selectedItem);
  169. }
  170. }
  171. };
  172. public boolean isOpen(){
  173. return isOpen;
  174. }
  175. private OnButtonClickListener onButtonClickListener;
  176. public interface OnButtonClickListener{
  177. void onButtonClick(View v,int id);
  178. }
  179. public void setOnButtonClickListener(OnButtonClickListener onButtonClickListener){
  180. this.onButtonClickListener=onButtonClickListener;
  181. }
  182. }
package com.ql.view;

import android.R.anim;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.view.animation.Animation.AnimationListener;
import android.widget.Button;
import android.widget.RelativeLayout;

import com.ql.app.R;

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 AnimButtons(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		this.context=context;
	}
	public AnimButtons(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		this.context=context;
	}
	
	@Override
	protected void onFinishInflate() {
		// TODO Auto-generated method stub
		super.onFinishInflate();
		View view=LayoutInflater.from(context).inflate(R.layout.anim_buttons, this);
		
		initButtons(view);
		
	}

	private void initButtons(View view){
		// TODO Auto-generated method stub
		//6个按钮,具体视情况而定
		btns=new Button[6];
		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;//20
		angle=(float)Math.PI/(2*(btns.length-1));
	}
	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		// TODO Auto-generated method stub
		super.onSizeChanged(w, h, oldw, oldh);
		final int bottomMargins=this.getMeasuredHeight()-buttonWidth-bottomMargin;
//		Log.i("tag", "bottomMargins====="+bottomMargins);
		btn_menu.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub					
				if(!isOpen){
					isOpen = true;
//					btn_menu.startAnimation(animRotate(-45.0f, 0.5f, 0.45f));
					for(int i=0;i<btns.length;i++){
						float xLenth=(float)(r*Math.sin(i*angle));
						float yLenth=(float)(r*Math.cos(i*angle));
//						Log.i("tag", "xLenth======"+xLenth+",yLenth======"+yLenth);
						btns[i].startAnimation(animTranslate(xLenth, -yLenth, leftMargin+(int)xLenth, bottomMargins - (int)yLenth, btns[i], minTimeSpent+i*intervalTimeSpent));
					}
					
				}
				else{					
					isOpen = false;
//					btn_menu.startAnimation(animRotate(90.0f, 0.5f, 0.45f));
					for(int i=0;i<btns.length;i++){
						float xLenth=(float)(r*Math.sin(i*angle));
						float yLenth=(float)(r*Math.cos(i*angle));
//						Log.i("tag", "xLenth======"+xLenth+",yLenth======"+yLenth);
						btns[i].startAnimation(animTranslate(-xLenth, yLenth, leftMargin, bottomMargins, btns[i], maxTimeSpent-i*intervalTimeSpent));
					}
				}
					
			}
		});
		
	}
	private Animation animScale(float toX, float toY){
		// TODO Auto-generated method stub
		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 animRotate(float toDegrees, float pivotXValue, float pivotYValue){
		// TODO Auto-generated method stub
		final Animation animation = new RotateAnimation(0, toDegrees, Animation.RELATIVE_TO_SELF, pivotXValue, Animation.RELATIVE_TO_SELF, pivotYValue);
		animation.setAnimationListener(new AnimationListener(){
			
			@Override
			public void onAnimationStart(Animation animation){
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onAnimationRepeat(Animation animation){
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onAnimationEnd(Animation animation){
				// TODO Auto-generated method stub
				animation.setFillAfter(true);
			}
		});
		return animation;
	}
	
	
	private Animation animTranslate(float toX, float toY, final int lastX, final int lastY,
			final Button button, long durationMillis){
		// TODO Auto-generated method stub
		Animation animation = new TranslateAnimation(0, toX, 0, toY);				
		animation.setAnimationListener(new AnimationListener(){
						
			@Override
			public void onAnimationStart(Animation animation){
				// TODO Auto-generated method stub
								
			}
						
			@Override
			public void onAnimationRepeat(Animation animation) {
				// TODO Auto-generated method stub
							
			}
						
			@Override
			public void onAnimationEnd(Animation animation){
				// TODO Auto-generated method stub
				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) {
			// TODO Auto-generated method stub
			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;
	}
}


布局anim_buttons.xml:

Xml代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:background="#FFF"
  7. >
  8. <Button android:id="@+id/btn_sleep"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:background="@drawable/composer_sleep"
  12. android:layout_alignParentLeft="true"
  13. android:layout_alignParentBottom="true"
  14. />
  15. <Button android:id="@+id/btn_thought"
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:background="@drawable/composer_thought"
  19. android:layout_alignParentLeft="true"
  20. android:layout_alignParentBottom="true"
  21. />
  22. <Button android:id="@+id/btn_music"
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:background="@drawable/composer_music"
  26. android:layout_alignParentLeft="true"
  27. android:layout_alignParentBottom="true"
  28. />
  29. <Button android:id="@+id/btn_place"
  30. android:layout_width="wrap_content"
  31. android:layout_height="wrap_content"
  32. android:background="@drawable/composer_place"
  33. android:layout_alignParentLeft="true"
  34. android:layout_alignParentBottom="true"
  35. />
  36. <Button android:id="@+id/btn_with"
  37. android:layout_width="wrap_content"
  38. android:layout_height="wrap_content"
  39. android:background="@drawable/composer_with"
  40. android:layout_alignParentLeft="true"
  41. android:layout_alignParentBottom="true"
  42. />
  43. <Button android:id="@+id/btn_camera"
  44. android:layout_width="wrap_content"
  45. android:layout_height="wrap_content"
  46. android:background="@drawable/composer_camera"
  47. android:layout_alignParentLeft="true"
  48. android:layout_alignParentBottom="true"
  49. />
  50. <Button android:id="@+id/btn_menu"
  51. android:layout_width="58dip"
  52. android:layout_height="58dip"
  53. android:background="@drawable/friends_delete"
  54. android:layout_alignParentLeft="true"
  55. android:layout_alignParentBottom="true"
  56. android:layout_marginLeft="10dip"
  57. android:layout_marginBottom="10dip"
  58. />
  59. </RelativeLayout>
<?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" 
	android:background="#FFF"
	>
	<Button android:id="@+id/btn_sleep"
		android:layout_width="wrap_content" 
		android:layout_height="wrap_content"
		android:background="@drawable/composer_sleep"
		android:layout_alignParentLeft="true"
		android:layout_alignParentBottom="true"
		/>

	<Button android:id="@+id/btn_thought"
		android:layout_width="wrap_content" 
		android:layout_height="wrap_content"
		android:background="@drawable/composer_thought"
		android:layout_alignParentLeft="true"
		android:layout_alignParentBottom="true"
		/>

	<Button android:id="@+id/btn_music"
		android:layout_width="wrap_content" 
		android:layout_height="wrap_content"
		android:background="@drawable/composer_music"
		android:layout_alignParentLeft="true"
		android:layout_alignParentBottom="true"
		/>

	<Button android:id="@+id/btn_place"
		android:layout_width="wrap_content" 
		android:layout_height="wrap_content"
		android:background="@drawable/composer_place"
		android:layout_alignParentLeft="true"
		android:layout_alignParentBottom="true"
		/>

	<Button android:id="@+id/btn_with"
		android:layout_width="wrap_content" 
		android:layout_height="wrap_content"
		android:background="@drawable/composer_with"
		android:layout_alignParentLeft="true"
		android:layout_alignParentBottom="true"
		/>

	<Button android:id="@+id/btn_camera"
		android:layout_width="wrap_content" 
		android:layout_height="wrap_content"
		android:background="@drawable/composer_camera"
		android:layout_alignParentLeft="true"
		android:layout_alignParentBottom="true"
		/>

	<Button android:id="@+id/btn_menu"
		android:layout_width="58dip" 
		android:layout_height="58dip"
		android:background="@drawable/friends_delete"
		android:layout_alignParentLeft="true"
		android:layout_alignParentBottom="true"
		android:layout_marginLeft="10dip"
		android:layout_marginBottom="10dip"
	/>
</RelativeLayout>



用法:

Java代码 复制代码 收藏代码
  1. public void onCreate(Bundle savedInstanceState){
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.main);
  4. AnimButtons animButtons=(AnimButtons)findViewById(R.id.animButtons);
  5. animButtons.setOnButtonClickListener(new AnimButtons.OnButtonClickListener() {
  6. @Override
  7. public void onButtonClick(View v, int id) {
  8. // TODO Auto-generated method stub
  9. Log.i("tag", "id============="+id);
  10. }
  11. });
  12. }
public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        AnimButtons animButtons=(AnimButtons)findViewById(R.id.animButtons);
        animButtons.setOnButtonClickListener(new AnimButtons.OnButtonClickListener() {
			
			@Override
			public void onButtonClick(View v, int id) {
				// TODO Auto-generated method stub
				Log.i("tag", "id============="+id);
			}
		});
        
    }


Xml代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:layout_width="fill_parent"
  8. android:layout_height="wrap_content"
  9. android:text="@string/hello" />
  10. <!-- layout_width,layout_height最好是fill_parent参数 -->
  11. <com.ql.view.AnimButtons
  12. android:id="@+id/animButtons"
  13. android:layout_width="fill_parent"
  14. android:layout_height="fill_parent"
  15. />
  16. </LinearLayout>
<?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" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
<!--  layout_width,layout_height最好是fill_parent参数 -->
	<com.ql.view.AnimButtons
	    android:id="@+id/animButtons"
	    android:layout_width="fill_parent"
        android:layout_height="fill_parent"
	    />
</LinearLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值