仿扇形菜单动画效果

来源:互联网 发布:java最常用的设计模式 编辑:程序博客网 时间:2024/04/30 14:17
转自;http://gundumw100.iteye.com/blog/1299953
http://www.oschina.net/code/snippet_577276_19821
记得在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(00);  
  175.                 params.height = buttonWidth;  
  176.                 params.width = buttonWidth;                                           
  177.                 params.setMargins(lastX, lastY, 00);  
  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.     }  
  218. }  

布局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.     }  

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>  


网上又找到一个相同效果的。呵呵。 
http://www.cnblogs.com/mudoot/archive/2012/01/19/path_composer_menu.html
  • PathButton.rar (165.2 KB)
  • 描述: 写在Activity中的,已不推荐下载
  • 下载次数: 134
  • AnimButtons.rar (161.1 KB)
  • 描述: 抽成控件,需要兼容性测试
  • 下载次数: 402
  • 查看图片附件
原创粉丝点击