Jelajahi Sumber

Merge pull request #4 from callmepeanut/master

Add circle pattern, thank you @callmepeanut.
Tristan Wiley 10 tahun lalu
induk
melakukan
f720c28349

+ 12 - 2
README.md

@@ -1,9 +1,19 @@
-# FloatingActionMenu
+#NEW README
+---
+This is a fork from https://github.com/TristanWiley/FloatingActionMenu, I modified it to support both  circle and line menu.
+The sample shows how to use it.
+## Example
+![](http://7lrzvb.com1.z0.glb.clouddn.com/test07.gif)
+
+
+#ORIGIN README
+---
+## FloatingActionMenu
 I got the original code from douo here - gist.github.com/douo/dfde289778a9b3b6918f
 
 I modified the code so it looks better, there's spacing between the buttons.  See the example on how to use it.
 
-# How to Use
+## How to Use
 
 1. Like any other library, put this in your Android project and add it as a dependency.
 2. You can also use jitpack.io if you want to use Maven.

+ 51 - 0
example/src/main/java/terranovaproductions/newcomicreader/sample/DemoCircleMenuFragment.java

@@ -0,0 +1,51 @@
+package terranovaproductions.newcomicreader.sample;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import terranovaproductions.newcomicreader.FloatingActionMenu;
+
+/**
+ * Created by renqinghe on 15-11-4.
+ */
+public class DemoCircleMenuFragment extends Fragment {
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.fragment_circle_menu, container, false);
+        initView(v);
+        return v;
+    }
+
+    private void initView(View v) {
+        FloatingActionMenu menu = (FloatingActionMenu) v.findViewById(R.id.fab_menu_circle);
+        menu.setMultipleOfFB(3.2f);
+        menu.setOnMenuItemClickListener(new FloatingActionMenu.OnMenuItemClickListener() {
+            @Override
+            public void onMenuItemClick(FloatingActionMenu fam, int index, FloatingActionButton item) {
+                String str = "";
+                switch (index) {
+                    case 0:
+                        str = "main fab is clicked!";
+                        break;
+                    case 1:
+                        str = "download fab is clicked!";
+                        break;
+                    case 2:
+                        str = "browser fab is clicked!";
+                        break;
+                    default:
+                }
+                Toast.makeText(getActivity().getApplicationContext(), str, Toast.LENGTH_SHORT).show();
+            }
+        });
+
+
+    }
+}

+ 25 - 0
example/src/main/java/terranovaproductions/newcomicreader/sample/DemoLineMenuFragment.java

@@ -0,0 +1,25 @@
+package terranovaproductions.newcomicreader.sample;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import terranovaproductions.newcomicreader.FloatingActionMenu;
+
+/**
+ * Created by renqinghe on 15-11-4.
+ */
+public class DemoLineMenuFragment extends Fragment {
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.fragment_line_menu, container, false);
+        FloatingActionMenu menu = (FloatingActionMenu) v.findViewById(R.id.fab_menu_line);
+        menu.setIsCircle(false);
+        menu.setmItemGap(48);
+        return v;
+    }
+}

+ 41 - 0
example/src/main/java/terranovaproductions/newcomicreader/sample/FragmentAdapter.java

@@ -0,0 +1,41 @@
+package terranovaproductions.newcomicreader.sample;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+
+import java.util.List;
+
+/**
+ * Created by renqinghe on 15-11-4.
+ */
+public class FragmentAdapter extends FragmentPagerAdapter {
+    private List<Fragment> mFragments;
+    private String tabTitles[];
+
+    public FragmentAdapter(FragmentManager fm, List<Fragment> mFragments) {
+        super(fm);
+        this.mFragments = mFragments;
+    }
+
+    public FragmentAdapter(FragmentManager fm, List<Fragment> mFragments, String[] tabTitles) {
+        super(fm);
+        this.mFragments = mFragments;
+        this.tabTitles = tabTitles;
+    }
+
+    @Override
+    public Fragment getItem(int position) {
+        return mFragments.get(position);
+    }
+
+    @Override
+    public int getCount() {
+        return mFragments.size();
+    }
+
+    @Override
+    public CharSequence getPageTitle(int position) {
+        return tabTitles[position];
+    }
+}

+ 32 - 0
example/src/main/java/terranovaproductions/newcomicreader/sample/MainActivity.java

@@ -1,13 +1,45 @@
 package terranovaproductions.newcomicreader.sample;
 
+import android.support.design.widget.TabLayout;
+import android.support.v4.app.Fragment;
+import android.support.v4.view.ViewPager;
 import android.support.v7.app.AppCompatActivity;
 import android.os.Bundle;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.List;
 
 public class MainActivity extends AppCompatActivity {
 
+    private ViewPager mViewPager;
+    private TabLayout mTabLayout;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
+
+        mViewPager = (ViewPager) findViewById(R.id.viewpager);
+        setupViewPager();
+
+        mTabLayout = (TabLayout) findViewById(R.id.home_tabs);
+        mTabLayout.setupWithViewPager(mViewPager);
+        mTabLayout.setTabMode(TabLayout.MODE_FIXED);
+    }
+
+    private void setupViewPager() {
+        List<Fragment> fragments = new ArrayList<>();
+        fragments.add(new DemoCircleMenuFragment());
+        fragments.add(new DemoLineMenuFragment());
+        FragmentAdapter adapter =
+                new FragmentAdapter(getSupportFragmentManager(), fragments, new String[]{"Circle", "Line"});
+        mViewPager.setAdapter(adapter);
+        mViewPager.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+
+            }
+        });
     }
 }

TEMPAT SAMPAH
example/src/main/res/drawable-xhdpi/ic_file_download_white_24dp.png


TEMPAT SAMPAH
example/src/main/res/drawable-xhdpi/ic_home_white_24dp.png


TEMPAT SAMPAH
example/src/main/res/drawable-xhdpi/ic_open_in_browser_white_24dp.png


+ 15 - 47
example/src/main/res/layout/activity_main.xml

@@ -1,54 +1,22 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:fab="http://schemas.android.com/apk/res-auto"
     android:id="@+id/comicView"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
-    <terranovaproductions.newcomicreader.FloatingActionMenu
-        android:id="@+id/fab_menu"
+    <android.support.design.widget.TabLayout
+        android:id="@+id/home_tabs"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:padding="16dp">
-
-        <!--First button as menu button-->
-        <android.support.design.widget.FloatingActionButton
-            android:id="@+id/fab_main"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_add_white_24dp"
-            fab:fabSize="normal"
-            fab:backgroundTint="@color/material_orange"/>
-
-        <!-- Other button as menu items-->
-        <android.support.design.widget.FloatingActionButton
-            android:id="@+id/fab_random"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="Hello World1"
-            android:paddingBottom="20dp"
-            fab:fabSize="mini"
-            fab:backgroundTint="@color/material_orange" />
-
-
-        <android.support.design.widget.FloatingActionButton
-            android:id="@+id/fab_download"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="Hello World2"
-            android:paddingBottom="20dp"
-            fab:fabSize="mini"
-            fab:backgroundTint="@color/material_orange"/>
-
-        <android.support.design.widget.FloatingActionButton
-            android:id="@+id/fab_browser"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="Hello World3"
-            android:paddingBottom="20dp"
-            fab:fabSize="mini"
-            fab:backgroundTint="@color/material_orange"/>
-
-    </terranovaproductions.newcomicreader.FloatingActionMenu>
+        android:layout_height="wrap_content"
+        fab:tabTextColor="@android:color/white"
+        fab:tabSelectedTextColor="@android:color/holo_green_light"
+        android:background="@android:color/holo_blue_light"/>
 
+    <android.support.v4.view.ViewPager
+        android:id="@+id/viewpager"
+        android:layout_width="match_parent"
+        android:layout_height="fill_parent"
+        android:background="@android:color/holo_green_light"/>
 
-</RelativeLayout>
+</LinearLayout>

+ 52 - 0
example/src/main/res/layout/fragment_circle_menu.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:fab="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical" android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/white">
+
+    <terranovaproductions.newcomicreader.FloatingActionMenu
+        android:id="@+id/fab_menu_circle"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginBottom="16dp"
+        android:layout_marginRight="16dp">
+
+        <!--First button as menu button-->
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab_main_circle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_add_white_24dp"
+            fab:fabSize="normal"
+            fab:backgroundTint="@color/material_orange"/>
+
+        <!-- Other button as menu items-->
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab_random_circle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_home_white_24dp"
+            fab:fabSize="mini"
+            fab:backgroundTint="@color/material_orange" />
+
+
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab_download_circle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_file_download_white_24dp"
+            fab:fabSize="mini"
+            fab:backgroundTint="@color/material_orange"/>
+
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab_browser_circle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_open_in_browser_white_24dp"
+            fab:fabSize="mini"
+            fab:backgroundTint="@color/material_orange"/>
+
+    </terranovaproductions.newcomicreader.FloatingActionMenu>
+
+</LinearLayout>

+ 52 - 0
example/src/main/res/layout/fragment_line_menu.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:layout_width="match_parent"
+    xmlns:fab="http://schemas.android.com/apk/res-auto"
+    android:layout_height="match_parent"
+    android:background="@android:color/holo_green_light">
+
+    <terranovaproductions.newcomicreader.FloatingActionMenu
+        android:id="@+id/fab_menu_line"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginBottom="16dp"
+        android:layout_marginRight="16dp">
+
+        <!--First button as menu button-->
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab_main"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_add_white_24dp"
+            fab:fabSize="normal"
+            fab:backgroundTint="@android:color/holo_red_light"/>
+
+        <!-- Other button as menu items-->
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab_random"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:contentDescription="Hello World1"
+            fab:fabSize="mini"
+            fab:backgroundTint="@android:color/holo_red_light" />
+
+
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab_download"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:contentDescription="Hello World2"
+            fab:fabSize="mini"
+            fab:backgroundTint="@android:color/holo_red_light"/>
+
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab_browser"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:contentDescription="Hello World3"
+            fab:fabSize="mini"
+            fab:backgroundTint="@android:color/holo_red_light"/>
+
+    </terranovaproductions.newcomicreader.FloatingActionMenu>
+
+</LinearLayout>

+ 134 - 84
library/src/main/java/terranovaproductions/newcomicreader/FloatingActionMenu.java

@@ -16,7 +16,6 @@ import android.support.design.widget.FloatingActionButton;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.GestureDetector;
-import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -34,51 +33,24 @@ public class FloatingActionMenu extends ViewGroup {
 
     static final TimeInterpolator DEFAULT_OPEN_INTERPOLATOR = new OvershootInterpolator();
     static final TimeInterpolator DEFAULT_CLOSE_INTERPOLATOR = new AnticipateInterpolator();
-    private static final long ANIMATION_DURATION = 300;
-    private static final int DEFAULT_CHILD_GRAVITY = Gravity.END | Gravity.BOTTOM;
-    Animator animator = new Animator() {
-        @Override
-        public long getStartDelay() {
-            return 0;
-        }
-
-        @Override
-        public void setStartDelay(long startDelay) {
-
-        }
 
-        @Override
-        public Animator setDuration(long duration) {
-            duration = 2;
-            return null;
-        }
-
-        @Override
-        public long getDuration() {
-            return 0;
-        }
-
-        @Override
-        public void setInterpolator(TimeInterpolator value) {
-
-        }
-
-        @Override
-        public boolean isRunning() {
-            return true;
-        }
-    };
     private FloatingActionButton mMenuButton;
     private ArrayList<FloatingActionButton> mMenuItems;
     private ArrayList<TextView> mMenuItemLabels;
     private ArrayList<ItemAnimator> mMenuItemAnimators;
-    private int mItemMargin;
     private AnimatorSet mOpenAnimatorSet = new AnimatorSet();
     private AnimatorSet mCloseAnimatorSet = new AnimatorSet();
     private ImageView mIcon;
+
     private boolean mOpen;
     private boolean animating;
     private boolean mIsSetClosedOnTouchOutside = true;
+    private long duration = 300;
+    private boolean isCircle = true;
+    private int mRadius = 256;
+    private float multipleOfFB = 0;
+    private int mItemGap = 0;
+
     private OnMenuItemClickListener onMenuItemClickListener;
     private OnMenuToggleListener onMenuToggleListener;
     GestureDetector mGestureDetector = new GestureDetector(getContext(),
@@ -101,7 +73,8 @@ public class FloatingActionMenu extends ViewGroup {
             if (v instanceof FloatingActionButton) {
                 int i = mMenuItems.indexOf(v);
                 if (onMenuItemClickListener != null) {
-                    onMenuItemClickListener.onMenuItemClick(FloatingActionMenu.this, i, (FloatingActionButton) v);
+                    onMenuItemClickListener
+                            .onMenuItemClick(FloatingActionMenu.this, i, (FloatingActionButton) v);
                 }
             } else if (v instanceof TextView) {
                 int i = mMenuItemLabels.indexOf(v);
@@ -126,7 +99,6 @@ public class FloatingActionMenu extends ViewGroup {
         super(context, attrs, defStyleAttr);
         mMenuItems = new ArrayList<>(5);
         mMenuItemAnimators = new ArrayList<>(5);
-
         mMenuItemLabels = new ArrayList<>(5);
         mIcon = new ImageView(context);
     }
@@ -192,19 +164,6 @@ public class FloatingActionMenu extends ViewGroup {
         }
     }
 
-//    Rect rect = new Rect();
-//    Paint paint = new Paint();
-//
-//    @Override
-//    protected boolean drawChild(@NonNull Canvas canvas, @NonNull View child, long drawingTime) {
-//        boolean b = super.drawChild(canvas, child, drawingTime);
-//        paint.setColor(0xFFFF0000);
-//        paint.setStyle(Paint.Style.STROKE);
-//        rect.set(child.getLeft(), child.getTop(), child.getRight(), child.getBottom());
-//        canvas.drawRect(rect, paint);
-//        return b;
-//    }
-
     protected void startOpenAnimator() {
         mOpenAnimatorSet.start();
         for (ItemAnimator anim : mMenuItemAnimators) {
@@ -254,7 +213,8 @@ public class FloatingActionMenu extends ViewGroup {
         for (int i = 0; i < mMenuItems.size(); i++) {
             FloatingActionButton fab = mMenuItems.get(i);
             TextView label = mMenuItemLabels.get(i);
-            maxChildWidth = Math.max(maxChildWidth, label.getMeasuredWidth() + fab.getMeasuredWidth() + mItemMargin);
+            maxChildWidth = Math.max(maxChildWidth,
+                    label.getMeasuredWidth() + fab.getMeasuredWidth());
 
         }
 
@@ -289,6 +249,7 @@ public class FloatingActionMenu extends ViewGroup {
         }
     }
 
+
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         System.out.println("onLayout:" + changed);
@@ -296,36 +257,71 @@ public class FloatingActionMenu extends ViewGroup {
             int right = r - getPaddingRight();
             int bottom = b - getPaddingBottom();
             int top = bottom - mMenuButton.getMeasuredHeight();
-
             mMenuButton.layout(right - mMenuButton.getMeasuredWidth(), top, right, bottom);
             int dw = (mMenuButton.getMeasuredWidth() - mIcon.getMeasuredWidth()) / 2;
             int dh = (mMenuButton.getMeasuredHeight() - mIcon.getMeasuredHeight()) / 2;
-            mIcon.layout(right - mIcon.getMeasuredWidth() - dw, bottom - mIcon.getMeasuredHeight() - dh, right - dw, bottom - dh);
-            for (int i = 0; i < mMenuItems.size(); i++) {
-                FloatingActionButton item = mMenuItems.get(i);
-                TextView label = mMenuItemLabels.get(i);
-
-                label.setBackgroundResource(R.drawable.rounded_corners);
-
-                bottom = top -= mMenuItems.get(i).getPaddingBottom(); //Add 10px padding
-
-                top -= item.getMeasuredHeight();
-                int width = item.getMeasuredWidth();
-                int d = (mMenuButton.getMeasuredWidth() - width) / 2;
-                item.layout(right - width - d, top, right - d, bottom);
-                d = (item.getMeasuredHeight() - label.getMeasuredHeight()) / 2;
-
-
-                label.layout(item.getLeft() - mItemMargin - label.getMeasuredWidth() - 50, item.getTop() + d, item.getLeft() - mItemMargin, item.getTop() + d + label.getMeasuredHeight());
-                if (!animating) {
-                    if (!mOpen) {
-                        item.setTranslationY(mMenuButton.getTop() - item.getTop());
-                        item.setVisibility(GONE);
-                        label.setVisibility(GONE);
-                    } else {
-                        item.setTranslationY(0);
-                        item.setVisibility(VISIBLE);
-                        label.setVisibility(VISIBLE);
+            mIcon.layout(right - mIcon.getMeasuredWidth() - dw,
+                    bottom - mIcon.getMeasuredHeight() - dh, right - dw, bottom - dh);
+
+            if (isCircle) {
+                if (mMenuItems.size() < 2) {
+                    Log.e("onLayout", "Floating Action Buttons must more then one!");
+                    return;
+                }
+                double angle = Math.PI/2d/(mMenuItems.size() - 1);
+                for (int i = 0; i < mMenuItems.size(); i++) {
+                    FloatingActionButton itemFB = mMenuItems.get(i);
+                    int fbWidth = itemFB.getMeasuredWidth();
+                    int fbHeight = itemFB.getMeasuredHeight();
+                    if (0 != multipleOfFB) {
+                        mRadius = (int) (fbWidth * multipleOfFB);
+                    }
+                    int itemDw = (mMenuButton.getMeasuredWidth() - fbWidth) / 2;
+                    int itemDh = (mMenuButton.getMeasuredHeight() - fbHeight) / 2;
+                    int itemX = (int) (mRadius*Math.cos(i*angle));
+                    int itemY = (int) (mRadius*Math.sin(i*angle));
+                    itemFB.layout(right - itemX - fbWidth - itemDw, bottom - itemY - fbHeight - itemDh,
+                            right - itemX - itemDw, bottom - itemY - itemDh);
+
+                    if (!animating) {
+                        if (!mOpen) {
+                            itemFB.setTranslationY(mMenuButton.getTop() - itemFB.getTop());
+                            itemFB.setTranslationX(mMenuButton.getLeft() - itemFB.getLeft());
+                            itemFB.setVisibility(GONE);
+                        } else {
+                            itemFB.setTranslationY(0);
+                            itemFB.setTranslationX(0);
+                            itemFB.setVisibility(VISIBLE);
+                        }
+                    }
+                }
+            } else {
+                for (int i = 0; i < mMenuItems.size(); i++) {
+                    FloatingActionButton item = mMenuItems.get(i);
+                    TextView label = mMenuItemLabels.get(i);
+
+                    label.setBackgroundResource(R.drawable.rounded_corners);
+                    bottom = top -= mItemGap;
+
+                    top -= item.getMeasuredHeight();
+                    int width = item.getMeasuredWidth();
+                    int d = (mMenuButton.getMeasuredWidth() - width) / 2;
+                    item.layout(right - width - d, top, right - d, bottom);
+                    d = (item.getMeasuredHeight() - label.getMeasuredHeight()) / 2;
+
+                    label.layout(item.getLeft() - label.getMeasuredWidth() - 50,
+                            item.getTop() + d, item.getLeft(),
+                            item.getTop() + d + label.getMeasuredHeight());
+                    if (!animating) {
+                        if (!mOpen) {
+                            item.setTranslationY(mMenuButton.getTop() - item.getTop());
+                            item.setVisibility(GONE);
+                            label.setVisibility(GONE);
+                        } else {
+                            item.setTranslationY(0);
+                            item.setVisibility(VISIBLE);
+                            label.setVisibility(VISIBLE);
+                        }
                     }
                 }
             }
@@ -408,8 +404,8 @@ public class FloatingActionMenu extends ViewGroup {
         mOpenAnimatorSet.setInterpolator(DEFAULT_OPEN_INTERPOLATOR);
         mCloseAnimatorSet.setInterpolator(DEFAULT_CLOSE_INTERPOLATOR);
 
-        mOpenAnimatorSet.setDuration(ANIMATION_DURATION);
-        mCloseAnimatorSet.setDuration(ANIMATION_DURATION);
+        mOpenAnimatorSet.setDuration(duration);
+        mCloseAnimatorSet.setDuration(duration);
 
         mOpenAnimatorSet.addListener(listener);
         mCloseAnimatorSet.addListener(listener);
@@ -501,15 +497,29 @@ public class FloatingActionMenu extends ViewGroup {
         public void startOpenAnimator() {
             mView.animate().cancel();
             playingOpenAnimator = true;
-            mView.animate().translationY(0).setInterpolator(DEFAULT_OPEN_INTERPOLATOR).start();
-            mMenuButton.animate().rotation(135f).setInterpolator(DEFAULT_OPEN_INTERPOLATOR).start();
+            mView.animate()
+                    .translationY(0)
+                    .translationX(0)
+                    .setInterpolator(DEFAULT_OPEN_INTERPOLATOR)
+                    .start();
+            mMenuButton.animate()
+                    .rotation(135f)
+                    .setInterpolator(DEFAULT_OPEN_INTERPOLATOR)
+                    .start();
         }
 
         public void startCloseAnimator() {
             mView.animate().cancel();
             playingOpenAnimator = false;
-            mView.animate().translationY((mMenuButton.getTop() - mView.getTop())).setInterpolator(DEFAULT_CLOSE_INTERPOLATOR).start();
-            mMenuButton.animate().rotation(0f).setInterpolator(DEFAULT_CLOSE_INTERPOLATOR).start();
+            mView.animate()
+                    .translationX(mMenuButton.getLeft() - mView.getLeft())
+                    .translationY((mMenuButton.getTop() - mView.getTop()))
+                    .setInterpolator(DEFAULT_CLOSE_INTERPOLATOR)
+                    .start();
+            mMenuButton.animate()
+                    .rotation(0f)
+                    .setInterpolator(DEFAULT_CLOSE_INTERPOLATOR)
+                    .start();
         }
 
         @Override
@@ -539,4 +549,44 @@ public class FloatingActionMenu extends ViewGroup {
         public void onAnimationRepeat(Animator animation) {
         }
     }
+
+    /**
+     * set as circle(default) or line pattern
+     * @param isCircle
+     */
+    public void setIsCircle(boolean isCircle) {
+        this.isCircle = isCircle;
+    }
+
+    /**
+     * set the radius of menu, default 256
+     * @param mRadius
+     */
+    public void setmRadius(int mRadius) {
+        this.mRadius = mRadius;
+    }
+
+    /**
+     * set radius as multiple of width of floating action button
+     * @param multipleOfFB
+     */
+    public void setMultipleOfFB(float multipleOfFB) {
+        this.multipleOfFB = multipleOfFB;
+    }
+
+    /**
+     * duration of anim, default 300
+     * @param duration
+     */
+    public void setDuration(long duration) {
+        this.duration = duration;
+    }
+
+    /**
+     * Only usefully in Line pattern
+     * @param mItemGap
+     */
+    public void setmItemGap(int mItemGap) {
+        this.mItemGap = mItemGap;
+    }
 }