国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android圓形旋轉菜單開發實例

2019-12-12 05:22:15
字體:
來源:轉載
供稿:網友

最近幫朋友做了一個動畫菜單,感覺有一定的實用價值,就在此給大家分享一下,先看看效果:

實現思路:

從圖中可以看出,這三個(或更多,需要自己再實現)菜單是圍繞著中心點旋轉的,旋轉分為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, attrs, 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), dip2px(context, 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, dip2px(context, 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, 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, int center_distance, float d, boolean right)   {   if(oldradus != 0)   {     progressBar.clearAnimation();     if(isright)     {       mRotateUpAnim = new RotateAnimation(bgdus, bgdus + 120,           Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,           0.5f);       bgdus += 120;     }     else     {       mRotateUpAnim = new RotateAnimation(bgdus, bgdus - 120,           Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,           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, int center_distance, float d, 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, -height / 2 + left, 0, 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, dip2px(context, 45), oldradus, 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 style="white-space:pre">  </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圓形旋轉菜單開發實例,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广东省| 安乡县| 乳源| 巴楚县| 平南县| 潍坊市| 道真| 海宁市| 连江县| 融水| 阿勒泰市| 桐乡市| 宁波市| 深州市| 武城县| 永城市| 万荣县| 锦屏县| 呼和浩特市| 马公市| 曲水县| 浮山县| 开阳县| 麻城市| 永川市| 双江| 萝北县| 商水县| 缙云县| 枣庄市| 于都县| 乌兰察布市| 南雄市| 东方市| 石台县| 龙泉市| 泰顺县| 万安县| 建平县| 和政县| 肃南|