content: package com.lvrenyang.pathbutton;
  
  
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.animation.Animation;
  import android.view.animation.Animation.AnimationListener;
  import android.view.animation.AnticipateInterpolator;
  import android.view.animation.OvershootInterpolator;
  import android.view.animation.RotateAnimation;
  import android.view.animation.TranslateAnimation;
  import android.widget.LinearLayout;
  import android.widget.RelativeLayout;
  
  public class myAnimations {
  
  	public final int R	;	// 半徑
  	public static byte
  		RIGHTBOTTOM=1,
  		CENTERBOTTOM=2,
  		LEFTBOTTOM=3,
  		LEFTCENTER=4,
  		LEFTTOP=5,
  		CENTERTOP=6,
  		RIGHTTOP=7,
  		RIGHTCENTER=8;
  	
  	private int pc; //位置代號
  	private ViewGroup clayout; //父laoyout
  	private final int amount; //有幾多個按鈕
  	private double fullangle=180.0;//在幾大嘅角度內排佈
  	private byte xOri=1,yOri=1;  //x、y值嘅方向，即系向上還是向下
  
  	
  	/**
  	  * 構造函數
  	  * @param comlayout 包裹彈出按鈕嘅layout
  	  * @param poscode 位置代號，分別對應RIGHTBOTTOM、CENTERBOTTOM、LEFTBOTTOM、LEFTCENTER、LEFTTOP、CENTERTOP、RIGHTTOP、RIGHTCENTER
  	  * @param radius 半徑
  	*/
  	public myAnimations(ViewGroup comlayout,int poscode,int radius){
  		this.pc=poscode;
  		this.clayout=comlayout;
  		this.amount=clayout.getChildCount();
  		this.R=radius;
  		if(poscode==RIGHTBOTTOM){      //右下角
  			fullangle=90;
  			xOri=-1;yOri=-1;
  		}else if(poscode==CENTERBOTTOM){//中下
  			fullangle=180;
  			xOri=-1;yOri=-1;
  		}else if(poscode==LEFTBOTTOM){  //左下角
  			fullangle=90;
  			xOri=1;yOri=-1;
  		}else if(poscode==LEFTCENTER){  //左中
  			fullangle=180;
  			xOri=1;yOri=-1;
  		}else if(poscode==LEFTTOP){     //左上角
  			fullangle=90;
  			xOri=1;yOri=1;
  		}else if(poscode==CENTERTOP){   //中上
  			fullangle=180;
  			xOri=-1;yOri=1;
  		}else if(poscode==RIGHTTOP){    //右上角
  			fullangle=90;
  			xOri=-1;yOri=1;
  		}else if(poscode==RIGHTCENTER){ //右中
  			fullangle=180;
  			xOri=-1;yOri=-1;
  		}
  	}
  
  
  	/**
  	  * 彈幾個按鈕出嚟
  	  * @param durationMillis 用幾多時間
  	*/
  	public void startAnimationsIn(int durationMillis) {
  		/*
  		List<TouchObject> preTouch = preTouch(clayout);
  		composerLayout layout = (composerLayout) clayout;
  		if (!layout.isInit())
  			layout.initTouches(preTouch);
  		layout.setShow(true);		
  		*/
  		for (int i = 0; i < clayout.getChildCount(); i++) {
  			final LinearLayout inoutimagebutton = (LinearLayout) clayout.getChildAt(i);			
  			double offangle=fullangle/(amount-1);
  			//double marginTop = Math.sin(offangle * i * Math.PI / 180) * R;
  			//double marginRight = Math.cos(offangle * i * Math.PI / 180) * R;
  			final double deltaY,deltaX;
  			if(pc==LEFTCENTER || pc==RIGHTCENTER){
  				deltaX = Math.sin(offangle * i * Math.PI / 180) * R;
  				deltaY = Math.cos(offangle * i * Math.PI / 180) * R;		
  			}else{
  				deltaY = Math.sin(offangle * i * Math.PI / 180) * R;
  				deltaX = Math.cos(offangle * i * Math.PI / 180) * R;
  			}
  			inoutimagebutton.setVisibility(View.VISIBLE);
  
  			Animation animation = new TranslateAnimation(0, (float)(xOri* deltaX), 0, (float)(yOri* deltaY));
  			/*
  			 * 如果呢句為true，因為佢實際after嘅位置係從物理位置計起，最後因為物理位置變化咗而長咗一倍；
  			 * （可以將animation嘅位置視為影子位置。開始先喐咗影子位置去x，物理位置仍喺0。呢個時候animation結束，就將物理位置移到x。由於set咗fillafter，所以影子對於物理位置又移多x，所以影子位置會變咗2x。所以呢度一定唔可以true嘅）
  			 * 但如果係false嘅話，估計因為animationEnd同after有少少時間差，而出現最後閃一閃，影子稍微喺2x嘅位置出現一瞬間又去返x。其實影響都唔算大，你部機可能睇唔倒添。但好似有少少掃灰塵入地毯底嘅感覺，問題並冇解決。
  			 * （只有彈出嘅時候有呢個問題，因為收埋嘅時候直接設咗visible做gone）
  			 animation.setFillAfter(true);
  			*/
  			animation.setFillEnabled(true);//加咗呢句嘢，最後就唔會閃一閃。（先用animation移影子位置、再用layoutParams喐物理位置~呢種方法就有呢個同唔同步嘅問題，除非你settimeout咁去改物理位置。例如一共要移x距離，用1秒去完成，每隔0.1秒就將佢物理位置改變x/10。）
  			animation.setDuration(durationMillis);
  			animation.setStartOffset((i * 100) / (-1 + clayout.getChildCount()));
  			animation.setInterpolator(new OvershootInterpolator(2F));
  
  			//喐
  			inoutimagebutton.startAnimation(animation);
  			//喐完就改埋嗰啲button嘅實際位置（animation只系外表去咗第度，實際位置依然喺返舊時嗰度）
  			//因為animation係異步嘅，如果直接start完animate就set按鈕嘅位置，就有可能佢未喐完就飛咗過去
  			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					
  					int l=inoutimagebutton.getLeft();
  		            int t=inoutimagebutton.getTop();
  		            RelativeLayout.LayoutParams lps = new RelativeLayout.LayoutParams(
  		          				LinearLayout.LayoutParams.WRAP_CONTENT,
  		          				LinearLayout.LayoutParams.WRAP_CONTENT
  		          	);
  		            lps.leftMargin=(int)(l+xOri* deltaX);
  		            lps.topMargin =(int)(t+yOri* deltaY);
  		            //System.out.println("oldleft: "+l+"   leftmargin: "+lps.leftMargin);
  		            //System.out.println("oldtop:  "+t+"   topmargin:  "+lps.topMargin);
  		            inoutimagebutton.setLayoutParams(lps);
  				}
  			});
  
  		}
  	}
  	
  	/**
  	  * 收埋幾個按鈕入去
  	  * @param durationMillis 用幾多時間
  	*/
  	public void startAnimationsOut( int durationMillis) {
  		for (int i = 0; i < clayout.getChildCount(); i++) {
  			final LinearLayout inoutimagebutton = (LinearLayout) clayout.getChildAt(i);
  			
  			double offangle=fullangle/(amount-1);
  			final double deltaY,deltaX;
  			if(pc==LEFTCENTER || pc==RIGHTCENTER){
  				deltaX = Math.sin(offangle * i * Math.PI / 180) * R;
  				deltaY = Math.cos(offangle * i * Math.PI / 180) * R;		
  			}else{
  				deltaY = Math.sin(offangle * i * Math.PI / 180) * R;
  				deltaX = Math.cos(offangle * i * Math.PI / 180) * R;
  			}
  			
  			Animation animation = new TranslateAnimation(0,-(float)(xOri*deltaX), 0,  -(float)(yOri*deltaY));
  			//animation.setFillAfter(true);
  			animation.setDuration(durationMillis);
  			animation.setStartOffset(((clayout.getChildCount() - i) * 100) / (-1 + clayout.getChildCount()));// 顺序倒一下比较舒服
  			animation.setInterpolator(new AnticipateInterpolator(2F));
  			//喐
  			inoutimagebutton.startAnimation(animation);
  			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					
  					int l=inoutimagebutton.getLeft();
  		            int t=inoutimagebutton.getTop();
  		            RelativeLayout.LayoutParams lps = new RelativeLayout.LayoutParams(
  		          				LinearLayout.LayoutParams.WRAP_CONTENT,
  		          				LinearLayout.LayoutParams.WRAP_CONTENT
  		          	);
  		            lps.leftMargin=(int)(l- xOri* deltaX);
  		            lps.topMargin =(int)(t- yOri* deltaY);
  		            //System.out.println("leftmargin: "+lps.leftMargin);
  		            //System.out.println("topmargin:  "+lps.topMargin);
  		            inoutimagebutton.setLayoutParams(lps);
  		            inoutimagebutton.setVisibility(View.GONE);
  				}
  			});
  		}
  
  	}
  	
  	/**
  	  * 獲取位置代碼（其實貌似都冇乜用）
  	*/
  	public int getPosCode(){
  		return this.pc;
  	}
  
  	/*
  	 *舊有內容，因為佢原來冇真正喐控件嘅物理位置，就要模擬返出點擊父layout時嘅位置，咁嘅話做onclicklistener會比較麻煩
  	private List<TouchObject> preTouch(ViewGroup viewgroup) {
  		List<TouchObject> objects = new ArrayList<TouchObject>();
  		for (int i = 0; i < viewgroup.getChildCount(); i++) {
  			final LinearLayout inoutimagebutton = (LinearLayout) viewgroup.getChildAt(i);
  			double marginTop = Math.sin(36.0 * i * Math.PI / 180) * R;
  			double marginRight = Math.cos(36.0 * i * Math.PI / 180) * R;
  			Point point = new Point((int) marginRight, (int) marginTop);
  			Rect animationRect = myAnimations.getAnimationRect(inoutimagebutton, point);
  			TouchObject obj = new TouchObject();
  			obj.setTouchId(inoutimagebutton.getId());
  			obj.setTouchArea(animationRect);
  			objects.add(obj);
  
  		}
  		return objects;
  	}
  
  	public static Rect getAnimationRect(LinearLayout btn, Point point) {
  		Rect r = new Rect();
  		r.left = btn.getLeft() - point.x;
  		r.top = btn.getTop() - point.y;
  		r.right = btn.getRight() - point.x;
  		r.bottom = btn.getBottom() - point.y;
  		return r;
  	}
  	*/
  
  	
  	
  	
  	
  	/**
  	  * 自轉函數（原本就有嘅靜態函數，未實體化都可以調用）
  	  * @param fromDegrees 從幾多度
  	  * @param toDegrees 到幾多度
  	  * @param durationMillis 轉幾耐
  	*/
  	public static Animation getRotateAnimation(float fromDegrees, float toDegrees, int durationMillis) {
  		RotateAnimation rotate = new RotateAnimation(fromDegrees, toDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
  		rotate.setDuration(durationMillis);
  		rotate.setFillAfter(true);
  		return rotate;
  	}
  	
  	
  	
  }