Android圆形旋转菜单开发实例

Android圆形旋转菜单开发实例,第1张

概述最近帮朋友做了一个动画菜单,感觉有一定的实用价值,就在此给大家分享一下,先看看效果:

最近帮朋友做了一个动画菜单,感觉有一定的实用价值,就在此给大家分享一下,先看看效果:

实现思路:

从图中可以看出,这三个(或更多,需要自己再实现)菜单是围绕着中心点旋转的,旋转分为2层,背景旋转和菜单旋转,背景旋转可以直接用旋转动画来实现;菜单的旋转是在以中心点为圆心的圆环上,所以这里用了根据旋转角度求此点在直角坐标系中的坐标点的函数(x = r * cos(rotation* 3.14 / 180) 和y = r * sin(rotation* 3.14 / 180) ),然后根据获取到的点的位置来设置菜单的位置就能实现这种效果。由此可见 数学是很重要的 哈哈~~

有了思路我们就能用代码来实现了:

1、首先自定义view继承相对布局并重写构造函数

/**  * Created by ywl on 2016/8/7.  */ public class CircleMenulayout extends relativeLayout {   public CircleMenulayout(Context context) {     this(context,null);   }   public CircleMenulayout(Context context,AttributeSet attrs) {     this(context,attrs,0);   }   /**    * 初始化布局 把旋转背景和中心点添加进去    * @param context    * @param attrs    * @param defStyleAttr    */   public CircleMenulayout(Context context,AttributeSet attrs,int defStyleAttr) {     super(context,defStyleAttr);     this.context = context;     layoutInflater = LayoutInflater.from(context);     menuitems = new ArrayList<VIEw>();     centervIEw = new VIEw(context);//中心点     centervIEw.setID(ID_CENTER_VIEW);     LayoutParams lp = new LayoutParams(0,0);     lp.addRule(relativeLayout.CENTER_IN_PARENT,relativeLayout.TRUE);     addVIEw(centervIEw,lp); //添加中心的 用于旋转定位     progressbar = new Progressbar(context);//旋转的背景     LayoutParams lp2 = new LayoutParams(dip2px(context,90),dip2px(context,90));     lp2.addRule(relativeLayout.CENTER_IN_PARENT,relativeLayout.TRUE);     addVIEw(progressbar,lp2);     progressbar.setIndeterminateDrawable(context.getResources().getDrawable(R.mipmap.icon_circle_menu));   } } 

构造函数中添加中心定位点和旋转背景图片,并设置合适的大小。

2、根据传入的图片数组和菜单名字数组,生成菜单原始位置效果。

/**    * 菜单的数量 和 半径 名字 和图片 这里只为3个菜单做了适配    * @param size    * @param center_distance    */   public voID initMenuItem(int size,int center_distance,String[] Titles,int[] imgs)   {     radus = 360f / size;     int wIDth = dip2px(context,50); //菜单宽度     int height = dip2px(context,50);//菜单高度     for(int i = 0; i < size; i++) //循环添加布局     {       int top = 0;       int left = 0;       top = -(int)(Math.sin(radus * i * 3.1415f / 180) * center_distance); //r  *  cos(ao  *  3.14  /180  )       left = -(int)(Math.cos(radus * i * 3.1415f / 180) * center_distance); //计算位置点       LayoutParams lp = new LayoutParams(dip2px(context,50),50));       VIEw vIEw = layoutInflater.inflate(R.layout.item_circle_menu,this,false);       vIEw.setTag(i);       TextVIEw tvname = (TextVIEw) vIEw.findVIEwByID(R.ID.tv_name);       ImageVIEw ivimg = (ImageVIEw) vIEw.findVIEwByID(R.ID.img);       tvname.setText(Titles[i]);       ivimg.setimageResource(imgs[i]);       vIEw.setonClickListener(new OnClickListener() {         @OverrIDe         public voID onClick(VIEw v) {//根据点击的区域 旋转菜单           if(!isrun) {             tag = (int) v.getTag();             currentposition = tag;             if(tag == 0)             {               finishdus = -360;             }             else if(tag == 1)             {               finishdus = -120;             }             else if(tag == 2)             {               finishdus = -240;             }             LayoutParams lp = (LayoutParams) v.getLayoutParams();             int l = lp.leftmargin;             int t = lp.topmargin;             if (t > -dip2px(context,5) && l > -dip2px(context,5)) {               oldradus = 120f;               isright = false;             } else if (t > -dip2px(context,5) && l < -dip2px(context,5)) {               oldradus = 120f;               isright = true;             } else if (t < -dip2px(context,5)) {               oldradus = 0f;             }             sub = 0;             circleMenu(8,45),oldradus,isright);           }         }       });       lp.addRule(relativeLayout.BELOW,centervIEw.getID());       lp.addRule(relativeLayout.RIGHT_OF,centervIEw.getID());       lp.setmargins(-wIDth / 2 + top,-height / 2 + left,0);       addVIEw(vIEw,lp);       menuitems.add(vIEw);     }     handler.postDelayed(runnable,0);   } 

根据菜单的数量循环计算每个菜单的位置,然后在相应的位置添加相应的菜单就可以实现菜单的初始化了。这里为每个菜单添加了点击事件,但是只适配了3个菜单的情况,至于其他数量的菜单,可以自己来改或者写一个通用的方法来计算点击位置。

3、背景旋转动画:

/**   * 根据度数来旋转菜单 菜单中心都在一个圆上面 采用圆周运动来旋转   * @param offserradius   * @param center_distance   * @param d   * @param right   */   public voID circleMenu(float offserradius,float d,boolean right)   {   if(oldradus != 0)   {     progressbar.clearanimation();     if(isright)     {       mRotateUpAnim = new RotateAnimation(bgdus,bgdus + 120,Animation.relative_TO_SELF,0.5f,0.5f);       bgdus += 120;     }     else     {       mRotateUpAnim = new RotateAnimation(bgdus,bgdus - 120,0.5f);       bgdus -= 120;     }     lir = new linearInterpolator();     mRotateUpAnim.setDuration(350);     mRotateUpAnim.setFillAfter(true);     mRotateUpAnim.setInterpolator(lir); //    mRotateUpAnim.setRepeatCount(Animation.INFINITE);     progressbar.startAnimation(mRotateUpAnim);   }     circleMenuItem(offserradius,center_distance,d,right);   } 

这个比较简单,就是根据旋转的角度,启用旋转动画。

4、旋转菜单:

/**    * 菜单旋转    * @param offserradius    * @param center_distance    * @param d    * @param right    */   public voID circleMenuItem(float offserradius,boolean right)   {     sub += offserradius;     if(sub > d)     {       if(onMenuItemSelectedListener != null)       {         onMenuItemSelectedListener.onMenuItemOnclick(tag);       }       isrun = false;       return;     }     if(right) {       offseTradus -= offserradius;     }     else     {       offseTradus += offserradius;     }     int size = menuitems.size();     int wIDth = dip2px(context,50);     int height = dip2px(context,50);     for(int i = 0; i < size; i++)     {       if(Math.abs(sub - d) <= 8)       {         offseTradus = finishdus;       }       LayoutParams lp = (LayoutParams) menuitems.get(i).getLayoutParams();       float ds = radus * i + offseTradus;       int top = -(int)(Math.sin(ds * 3.1415f / 180) * center_distance); //r  *  cos(ao  *  3.14  /180  )       int left = -(int)(Math.cos(ds * 3.1415f / 180) * center_distance);       lp.setmargins(-wIDth / 2 + top,0);       menuitems.get(i).requestLayout();     }     if(sub <= d) {       isrun = true;       offseTradus = offseTradus % 360;       handler.postDelayed(runnable,5);     }     else     {       if(onMenuItemSelectedListener != null)       {         onMenuItemSelectedListener.onMenuItemOnclick(tag);       }       isrun = false;     }   } 

这里旋转是根据初始化时每个菜单所在的位置来求的旋转角度,然后启动handler来动递加或递减角度来求响应的位置,就实现了动画效果。

5、手动设置菜单项(有局限,没有通用性):

/**    * 设置旋转到哪个菜单项    * @param tag    */   public voID setCurrentTag(int tag)   {     if(currentposition == tag)     {       return;     }     if(tag == 0)     {       finishdus = -360;     }     else if(tag == 1)     {       finishdus = -120;     }     else if(tag == 2)     {       finishdus = -240;     }     if(currentposition == 0) //当前是0     {       if(tag == 1)       {         oldradus = 120f;         isright = true;       }       else if(tag == 2)       {         oldradus = 120f;         isright = false;       }     }     else if(currentposition == 1)     {       if(tag == 2)       {         oldradus = 120f;         isright = true;       }       else if(tag == 0)       {         oldradus = 120f;         isright = false;       }     }     else if(currentposition == 2)     {       if(tag == 0)       {         oldradus = 120f;         isright = true;       }       else if(tag == 1)       {         oldradus = 120f;         isright = false;       }     }     currentposition = tag;     this.tag = tag;     sub = 0;     circleMenu(8,isright);   } 

这样就可以实现旋转效果了。

6、调用方法:

(1)布局文件:

<com.ywl5320.circlemenu.CircleMenulayout     androID:ID="@+ID/cml_menu"     androID:layout_wIDth="150dp"     androID:layout_height="150dp"     androID:layout_centerHorizontal="true"     androID:layout_alignParentBottom="true"     androID:layout_marginBottom="92dp"/> 

(2)菜单布局文件:

<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"   androID:orIEntation="vertical"    androID:layout_wIDth="100dp"   androID:layout_height="100dp"   androID:padding="5dp"   androID:gravity="center">   <ImageVIEw     androID:ID="@+ID/img"     androID:layout_wIDth="25dp"     androID:layout_height="25dp"     androID:scaleType="fitXY"/>   <TextVIEw     androID:ID="@+ID/tv_name"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:text="菜单项"     androID:textSize="9sp"     androID:gravity="center"     androID:textcolor="#ffffff"/> </linearLayout> 

(3)Activity中调用

<span >  </span>cmlmenu = (CircleMenulayout) findVIEwByID(R.ID.cml_menu);     btn = (button) findVIEwByID(R.ID.btn);     cmlmenu.initDatas(Titles,imgs);     cmlmenu.setonMenuItemSelectedListener(new CircleMenulayout.OnMenuItemSelectedListener() {       @OverrIDe       public voID onMenuItemOnclick(int code) {         if(code == 0)//         {           Toast.makeText(MainActivity.this,"支付宝",Toast.LENGTH_SHORT).show();         }         else if(code == 1)         {           Toast.makeText(MainActivity.this,"银联",Toast.LENGTH_SHORT).show();         }         else if(code == 2)         {           Toast.makeText(MainActivity.this,"微信",Toast.LENGTH_SHORT).show();         }       }     }); 

OK,就完成了三个菜单旋转效果(注:这里仅仅是为了3个菜单而设计的,其他个数的自己还需要精简或更改一些代码,相信自己改出来的会更有收获的~~)。

以上所述是小编给大家介绍的AndroID圆形旋转菜单开发实例,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

总结

以上是内存溢出为你收集整理的Android圆形旋转菜单开发实例全部内容,希望文章能够帮你解决Android圆形旋转菜单开发实例所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1148309.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存