仿的一個動畫菜單效果

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

 

記得在eoe上有人發過,但代碼質量不好。我重寫了一下,抽成了控件。但沒有經過各種控件的相容性測試,如果和其他控件的相容性不好,就直接在activity中寫代碼吧,應該差不多的。
我用的是平板,所以效果還行,不知道手機如何。




代碼:

Java代碼 複製代碼 收藏代碼
  1. package com.ql.view; 
  2.  
  3. import android.R.anim; 
  4. import android.content.Context; 
  5. import android.util.AttributeSet; 
  6. import android.util.Log; 
  7. import android.view.LayoutInflater; 
  8. import android.view.View; 
  9. import android.view.animation.Animation; 
  10. import android.view.animation.RotateAnimation; 
  11. import android.view.animation.ScaleAnimation; 
  12. import android.view.animation.TranslateAnimation; 
  13. import android.view.animation.Animation.AnimationListener; 
  14. import android.widget.Button; 
  15. import android.widget.RelativeLayout; 
  16.  
  17. import com.ql.app.R; 
  18.  
  19. public class AnimButtons extends RelativeLayout{ 
  20.  
  21.     private Context context; 
  22.     private int leftMargin=0,bottomMargin=0
  23.     private final int buttonWidth=58;//圖片寬高 
  24.     private final int r=180;//半徑 
  25.     private final int maxTimeSpent=200;//最長動畫耗時 
  26.     private final int minTimeSpent=80;//最短動畫耗時 
  27.     private int intervalTimeSpent;//每相鄰2個的時間間隔 
  28.     private Button[] btns; 
  29.     private Button btn_menu; 
  30.     private RelativeLayout.LayoutParams params; 
  31.     private boolean isOpen = false;//是否菜單打開狀態 
  32.     private float angle;//每個按鈕之間的夾角 
  33.     public AnimButtons(Context context) { 
  34.         super(context); 
  35.         // TODO Auto-generated constructor stub 
  36.         this.context=context; 
  37.     } 
  38.     public AnimButtons(Context context, AttributeSet attrs) { 
  39.         super(context, attrs); 
  40.         // TODO Auto-generated constructor stub 
  41.         this.context=context; 
  42.     } 
  43.      
  44.     @Override 
  45.     protected void onFinishInflate() { 
  46.         // TODO Auto-generated method stub 
  47.         super.onFinishInflate(); 
  48.         View view=LayoutInflater.from(context).inflate(R.layout.anim_buttons, this); 
  49.          
  50.         initButtons(view); 
  51.          
  52.     } 
  53.  
  54.     private void initButtons(View view){ 
  55.         // TODO Auto-generated method stub 
  56.         //6個按鈕,具體視情況而定 
  57.         btns=new Button[6]; 
  58.         btns[0] = (Button) view.findViewById(R.id.btn_camera); 
  59.         btns[1] = (Button) view.findViewById(R.id.btn_with); 
  60.         btns[2] = (Button) view.findViewById(R.id.btn_place); 
  61.         btns[3] = (Button) view.findViewById(R.id.btn_music); 
  62.         btns[4] = (Button) view.findViewById(R.id.btn_thought); 
  63.         btns[5] = (Button) view.findViewById(R.id.btn_sleep); 
  64.         btn_menu = (Button) view.findViewById(R.id.btn_menu); 
  65.          
  66.         leftMargin=((RelativeLayout.LayoutParams)(btn_menu.getLayoutParams())).leftMargin; 
  67.         bottomMargin=((RelativeLayout.LayoutParams)(btn_menu.getLayoutParams())).bottomMargin; 
  68.          
  69.         for(int i=0;i<btns.length;i++){ 
  70.             btns[i].setLayoutParams(btn_menu.getLayoutParams());//初始化的時候按鈕都重合 
  71.             btns[i].setTag(String.valueOf(i)); 
  72.             btns[i].setOnClickListener(clickListener); 
  73.         } 
  74.          
  75.         intervalTimeSpent=(maxTimeSpent-minTimeSpent)/btns.length;//20 
  76.         angle=(float)Math.PI/(2*(btns.length-1)); 
  77.     } 
  78.      
  79.     @Override 
  80.     protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
  81.         // TODO Auto-generated method stub 
  82.         super.onSizeChanged(w, h, oldw, oldh); 
  83.         final int bottomMargins=this.getMeasuredHeight()-buttonWidth-bottomMargin; 
  84. //      Log.i("tag", "bottomMargins====="+bottomMargins); 
  85.         btn_menu.setOnClickListener(new OnClickListener() { 
  86.              
  87.             @Override 
  88.             public void onClick(View v) { 
  89.                 // TODO Auto-generated method stub                   
  90.                 if(!isOpen){ 
  91.                     isOpen = true
  92. //                  btn_menu.startAnimation(animRotate(-45.0f, 0.5f, 0.45f)); 
  93.                     for(int i=0;i<btns.length;i++){ 
  94.                         float xLenth=(float)(r*Math.sin(i*angle)); 
  95.                         float yLenth=(float)(r*Math.cos(i*angle)); 
  96. //                      Log.i("tag", "xLenth======"+xLenth+",yLenth======"+yLenth); 
  97.                         btns[i].startAnimation(animTranslate(xLenth, -yLenth, leftMargin+(int)xLenth, bottomMargins - (int)yLenth, btns[i], minTimeSpent+i*intervalTimeSpent)); 
  98.                     } 
  99.                      
  100.                 } 
  101.                 else{                    
  102.                     isOpen = false
  103. //                  btn_menu.startAnimation(animRotate(90.0f, 0.5f, 0.45f)); 
  104.                     for(int i=0;i<btns.length;i++){ 
  105.                         float xLenth=(float)(r*Math.sin(i*angle)); 
  106.                         float yLenth=(float)(r*Math.cos(i*angle)); 
  107. //                      Log.i("tag", "xLenth======"+xLenth+",yLenth======"+yLenth); 
  108.                         btns[i].startAnimation(animTranslate(-xLenth, yLenth, leftMargin, bottomMargins, btns[i], maxTimeSpent-i*intervalTimeSpent)); 
  109.                     } 
  110.                 } 
  111.                      
  112.             } 
  113.         }); 
  114.          
  115.     } 
  116.     private Animation animScale(float toX, float toY){ 
  117.         // TODO Auto-generated method stub 
  118.         Animation animation = new ScaleAnimation(1.0f, toX, 1.0f, toY, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 
  119.         animation.setInterpolator(context, anim.accelerate_decelerate_interpolator); 
  120.         animation.setDuration(400); 
  121.         animation.setFillAfter(false); 
  122.         return animation; 
  123.          
  124.     } 
  125.      
  126.     private Animation animRotate(float toDegrees, float pivotXValue, float pivotYValue){ 
  127.         // TODO Auto-generated method stub 
  128.         final Animation animation = new RotateAnimation(0, toDegrees, Animation.RELATIVE_TO_SELF, pivotXValue, Animation.RELATIVE_TO_SELF, pivotYValue); 
  129.         animation.setAnimationListener(new AnimationListener(){ 
  130.              
  131.             @Override 
  132.             public void onAnimationStart(Animation animation){ 
  133.                 // TODO Auto-generated method stub 
  134.                  
  135.             } 
  136.              
  137.             @Override 
  138.             public void onAnimationRepeat(Animation animation){ 
  139.                 // TODO Auto-generated method stub 
  140.                  
  141.             } 
  142.              
  143.             @Override 
  144.             public void onAnimationEnd(Animation animation){ 
  145.                 // TODO Auto-generated method stub 
  146.                 animation.setFillAfter(true); 
  147.             } 
  148.         }); 
  149.         return animation; 
  150.     } 
  151.      
  152.      
  153.     private Animation animTranslate(float toX, float toY, final int lastX, final int lastY, 
  154.             final Button button, long durationMillis){ 
  155.         // TODO Auto-generated method stub 
  156.         Animation animation = new TranslateAnimation(0, toX, 0, toY);                
  157.         animation.setAnimationListener(new AnimationListener(){ 
  158.                          
  159.             @Override 
  160.             public void onAnimationStart(Animation animation){ 
  161.                 // TODO Auto-generated method stub 
  162.                                  
  163.             } 
  164.                          
  165.             @Override 
  166.             public void onAnimationRepeat(Animation animation) { 
  167.                 // TODO Auto-generated method stub 
  168.                              
  169.             } 
  170.                          
  171.             @Override 
  172.             public void onAnimationEnd(Animation animation){ 
  173.                 // TODO Auto-generated method stub 
  174.                 params = new RelativeLayout.LayoutParams(0, 0); 
  175.                 params.height = buttonWidth; 
  176.                 params.width = buttonWidth;                                          
  177.                 params.setMargins(lastX, lastY, 0, 0); 
  178.                 button.setLayoutParams(params); 
  179.                 button.clearAnimation(); 
  180.                          
  181.             } 
  182.         });                                                                                              
  183.         animation.setDuration(durationMillis); 
  184.         return animation; 
  185.     } 
  186.      
  187.     View.OnClickListener clickListener=new View.OnClickListener(){ 
  188.  
  189.         @Override 
  190.         public void onClick(View v) { 
  191.             // TODO Auto-generated method stub 
  192.             int selectedItem=Integer.parseInt((String)v.getTag()); 
  193.             for(int i=0;i<btns.length;i++){ 
  194.                 if(i==selectedItem){ 
  195.                     btns[i].startAnimation(animScale(2.0f, 2.0f)); 
  196.                 }else
  197.                     btns[i].startAnimation(animScale(0.0f, 0.0f)); 
  198.                 } 
  199.             } 
  200.             if(onButtonClickListener!=null){ 
  201.                 onButtonClickListener.onButtonClick(v, selectedItem); 
  202.             } 
  203.         } 
  204.          
  205.     }; 
  206.      
  207.     public boolean isOpen(){ 
  208.         return isOpen; 
  209.     } 
  210.      
  211.     private OnButtonClickListener onButtonClickListener; 
  212.     public interface OnButtonClickListener{ 
  213.         void onButtonClick(View v,int id); 
  214.     } 
  215.     public void setOnButtonClickListener(OnButtonClickListener onButtonClickListener){ 
  216.         this.onButtonClickListener=onButtonClickListener; 
  217.     } 
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.  
  16.     <Button android:id="@+id/btn_thought" 
  17.         android:layout_width="wrap_content"  
  18.         android:layout_height="wrap_content" 
  19.         android:background="@drawable/composer_thought" 
  20.         android:layout_alignParentLeft="true" 
  21.         android:layout_alignParentBottom="true" 
  22.         /> 
  23.  
  24.     <Button android:id="@+id/btn_music" 
  25.         android:layout_width="wrap_content"  
  26.         android:layout_height="wrap_content" 
  27.         android:background="@drawable/composer_music" 
  28.         android:layout_alignParentLeft="true" 
  29.         android:layout_alignParentBottom="true" 
  30.         /> 
  31.  
  32.     <Button android:id="@+id/btn_place" 
  33.         android:layout_width="wrap_content"  
  34.         android:layout_height="wrap_content" 
  35.         android:background="@drawable/composer_place" 
  36.         android:layout_alignParentLeft="true" 
  37.         android:layout_alignParentBottom="true" 
  38.         /> 
  39.  
  40.     <Button android:id="@+id/btn_with" 
  41.         android:layout_width="wrap_content"  
  42.         android:layout_height="wrap_content" 
  43.         android:background="@drawable/composer_with" 
  44.         android:layout_alignParentLeft="true" 
  45.         android:layout_alignParentBottom="true" 
  46.         /> 
  47.  
  48.     <Button android:id="@+id/btn_camera" 
  49.         android:layout_width="wrap_content"  
  50.         android:layout_height="wrap_content" 
  51.         android:background="@drawable/composer_camera" 
  52.         android:layout_alignParentLeft="true" 
  53.         android:layout_alignParentBottom="true" 
  54.         /> 
  55.  
  56.     <Button android:id="@+id/btn_menu" 
  57.         android:layout_width="58dip"  
  58.         android:layout_height="58dip" 
  59.         android:background="@drawable/friends_delete" 
  60.         android:layout_alignParentLeft="true" 
  61.         android:layout_alignParentBottom="true" 
  62.         android:layout_marginLeft="10dip" 
  63.         android:layout_marginBottom="10dip" 
  64.     /> 
  65. </RelativeLayout> 



用法:

Java代碼 複製代碼 收藏代碼
  1. public void onCreate(Bundle savedInstanceState){ 
  2.         super.onCreate(savedInstanceState); 
  3.         setContentView(R.layout.main); 
  4.          
  5.         AnimButtons animButtons=(AnimButtons)findViewById(R.id.animButtons); 
  6.         animButtons.setOnButtonClickListener(new AnimButtons.OnButtonClickListener() { 
  7.              
  8.             @Override 
  9.             public void onButtonClick(View v, int id) { 
  10.                 // TODO Auto-generated method stub 
  11.                 Log.i("tag", "id============="+id); 
  12.             } 
  13.         }); 
  14.          
  15.     } 
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.  
  7.     <TextView 
  8.         android:layout_width="fill_parent" 
  9.         android:layout_height="wrap_content" 
  10.         android:text="@string/hello" /> 
  11. <!--  layout_width,layout_height最好是fill_parent參數 --> 
  12.     <com.ql.view.AnimButtons 
  13.         android:id="@+id/animButtons" 
  14.         android:layout_width="fill_parent" 
  15.         android:layout_height="fill_parent" 
  16.         /> 
  17. </LinearLayout> 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章