Recently to help Friends do an animated menu, feel a certain practical value, here to share with you, first look at the effect:
Realize the idea:
As you can see from the diagram, these three (or more, need to realize) the menu revolves around the center point, the rotation is divided into 2 layers, background rotation and menu rotation, background rotation can be directly achieved by rotating animation; The menu is rotated on a circle centered around the center point, So here's a function to find the coordinates of this point in a rectangular coordinate system based on the rotation angle (x = R * cos (rotation* 3.14/180) and y = R * sin (rotation* 3.14/180)), and then set the location of the menu based on the location of the obtained point can achieve this effect. This shows that mathematics is very important haha ~ ~
With the idea we can use code to achieve:
1. Customize view inheritance relative layout and override constructor first
/** * Created by YWL on 2016/8/7. * * public class Circlemenulayout extends Relativelayout {public Circlemenulayout (context) {The context
, null);
Public Circlemenulayout (context, AttributeSet attrs) {This (context, attrs, 0); /** * Initialization layout adds rotation background and center point to * @param context * @param attrs * @param defstyleattr/Public Circ
Lemenulayout (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr);
This.context = context;
Layoutinflater = Layoutinflater.from (context);
MenuItems = new arraylist<view> ();
Centerview = new View (context);//center point Centerview.setid (Id_center_view);
Layoutparams LP = new Layoutparams (0, 0);
Lp.addrule (Relativelayout.center_in_parent, relativelayout.true); AddView (Centerview, LP); Add Center for rotation positioning ProgressBar = new ProgressBar (context)//rotate background layoutparams LP2 = new Layoutparams (dip2px , dip2px (Context, 90));
Lp2.addrule (Relativelayout.center_in_parent, relativelayout.true);
AddView (ProgressBar, LP2);
Progressbar.setindeterminatedrawable (Context.getresources (). getdrawable (R.mipmap.icon_circle_menu)); }
}
constructor to add a central anchor point and rotate the background picture, and set the appropriate size.
2, according to the incoming picture array and menu name array, generate menu original position effect.
/** * The number and radius of the menu and the name and picture here only 3 menus are fitted * @param size * @param center_distance/public void Initmenuite
m (int size, int center_distance, string[] titles, int[] imgs) {radus = 360f/size; int width = dip2px (context, 50); Menu width int height = dip2px (context, 50)//menu height for (int i = 0; i < size; i++)//loop add layout {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);
Compute location POINT Layoutparams LP = new Layoutparams (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) {//Rotate menu based on clicked area
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,), 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); }
According to the number of menus to cycle the position of each menu, and then add a corresponding menu in the appropriate location to implement the menu initialization. Click events are added for each menu, but only 3 menus are available, as with the number of other menus, you can either change it yourself or write a generic method to calculate the click position.
3, background rotation animation:
/** * Rotate the menu Center on a per-degree basis with circular motion on top of a circle * @param offserradius * @param center_distance * @param d * @param r ight */public void Circlemenu (float offserradius, int center_distance, float D, Boolean right) {if (Oldradus
!= 0) {progressbar.clearanimation (); if (isright) {Mrotateupanim = new rotateanimation (Bgdus, Bgdus +, 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); }
This is relatively simple, that is, based on the rotation angle, enable the rotation animation.
4. Rotate the menu:
/** * Menu Rotation * @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.onmenuite
Monclick (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.onmenuitemon
Click (tag);
} Isrun = false; }
}
Here the rotation is based on the initialization of the location of each menu to find the rotation angle, and then start handler to move accumulator or descending angle to find the location of the response, the animation effect achieved.
5. Set menu items manually (limited, no versatility):
/** * Settings rotate to which menu item * @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)//is currently 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,), Oldradus, isright); }
This will enable the rotation effect.
6. Calling Method:
(1) Layout file:
<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"
(2) Menu layout file:
<?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= "menu item"
android:textsize= "9sp"
android:gravity= "center"
Android:textcolor= "#ffffff"/>
(3) Call in 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, "Alipay", Toast.length_short). Show ();
else if (code = = 1)
{
toast.maketext (mainactivity.this, "UnionPay", Toast.length_short). Show ()
;
else if (code = = 2)
{
toast.maketext (mainactivity.this, "micro-letter", Toast.length_short). Show ();
}
OK, finished three menu rotation effect (Note: This is only for the 3 menu design, the other number of their own also need to streamline or change some code, I believe that the change will be more fruitful ~ ~).
The above is a small set to introduce the Android round rotating menu development examples, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!