StarMenu
Easy and Fast Way to build Context Menus

Pub Version Pub Likes Pub Likes Pub Likes GitHub repo size GitHub forks GitHub stars GitHub license

A simple way to attach a popup menu to any widget with any widget as menu entries. Menu entry widgets can bind a sub-menu with different shapes. Multiple ways to fine-tune animation and position.

Image Image

Every widgets can be tapped to display a popup menu! There are currently 3 shapes to choose:

  • linear: items are lined by a given angle with a given space between them and with a 3-way alignment.
  • circle: items are lined up in a circle shape with a given radius and a star-end angle.
  • grid: items are aligned in a grid shape with N columns and a given horizontal and vertical space.
ImageImageImage
linearcirclepanel

Please take a look at main.dart and main_more.dart in the example/lib dir for the examples.

Using the package is pretty simple:

  • install the package with flutter pub add star_menu
  • feed the items parameter with the menu entry widgets list
  • set the params with StarMenuParameters
  • set the child with a widget you like to press to open the menu
StarMenu(
  params: StarMenuParameters(),
  onStateChanged: (state) => print('State changed: $state'),
  onItemTapped: (index, controller) {
    // here you can programmatically close the menu
    if (index == 7)
      controller.closeMenu();
	print('Menu item $index tapped');
  }),
  items: entries,
  child: FloatingActionButton(
    onPressed: () {print('FloatingActionButton tapped');},
    child: Icon(Icons.looks_one),
  ),
)
  • onStateChanged triggers menu state canges:
enum MenuState {
  closed,
  closing,
  opening,
  open,
}
  • items parameter is used when entries are known. If you want to build items in runtime use lazyItems, ie when StarMenu is already builded in the widget tree, but the menu items changed:
StarMenu(
  ...
  lazyItems: () async{
      return [
        Container(
          color: Color.fromARGB(255, Random().nextInt(255),
              Random().nextInt(255), Random().nextInt(255)),
          width: 60,
          height: 40,
          child: Text(userName),
        ),
        ...
      ];
  }
)

lazyItems is a callback function which returns Future<List<Widget>> which is called before opening the menu. Only lazyItems or items can be used.

StarMenu can be created also with addStarMenu() widget extension:

FloatingActionButton(
  onPressed: () {print('FloatingActionButton tapped');},
  child: Icon(Icons.looks_one),
).addStarMenu(
	context, 
	entries, 
	StarMenuParameters(), 
	onItemTapped: (index, controller) {}),

StarMenuParameters

Class to define all the parameters for the shape, animation and menu behavior.

NameTypeDefaultsDescription
shapeenumMenuShape.circleMenu shape kind. Could be MenuShape.circle, MenuShape.linear, MenuShape.grid.
boundaryBackgroundclass-See below.
linearShapeParamsclass-See below.
circleShapeParamsclass-See below.
gridShapeParamsclass-See below.
backgroundParamsclass-See below.
openDurationMsint400Open animation duration ms.
closeDurationMsint150Close animation duration ms.
rotateItemsAnimationAngledouble0.0Starting rotation angle of the items that will reach 0 DEG when animation ends.
startItemScaleAnimationdouble0.3Starting scale of the items that will reach 1 when animation ends.
centerOffsetOffsetOffset.zeroShift offset of menu center from the center of parent widget.
useScreenCenterboolfalseUse the screen center instead of parent widget center.
checkItemsScreenBoundariesboolfalseChecks if the whole menu boundaries exceed screen edges, if so set it in place to be all visible.
checkMenuScreenBoundariesbooltrueChecks if items exceed screen edges, if so set them in place to be visible.
animationCurveCurveCurves.fastOutSlowInAnimation curve kind to use.
useLongPressboolfalseUse long press instead of a tap to open the menu.
longPressDurationDuration500 msThe timing to trigger long press.
onHoverScaledouble1.0Scale item when mouse is hover (desktop only)

There are some StarMenuParameters factory presets with which you can set StarMenu.params

StarMenuParameters.dropdown(BuildContext context)Image
StarMenuParameters.panel(BuildContext context, {int columns = 3})Image

StarMenuParameters.arc(BuildContext context, ArcType type, {double radiusX = 130, double radiusY = 130})

typeresult
ArcType.semiUpImage
ArcType.semiDownImage
ArcType.semiLeftImage
ArcType.semiRightImage
ArcType.quarterTopRightImage
ArcType.quarterTopLeftImage
ArcType.quarterBottomRightImage
ArcType.quarterBottomLeftImage

BoundaryBackground

NameTypeDefaultsDescription
colorColor0x80000000color of the boundary background.
paddingEdgeInsetsEdgeInsets.all(8.0)Padding of the boundary background.
decorationDecorationBorderRadius.circular(8)background Container widget decoration.

LinearShapeParams

NameTypeDefaultsDescription
angledouble90.0Degree angle. Anticlockwise with 0° on 3 o'clock.
spacedouble0.0Space between items.
alignmentLinearAlignmentcenterleft, center, right, top, bottom. Useful when the linear shape is vertical or horizontal.

CircleShapeParams

NameTypeDefaultsDescription
radiusXdouble100.0Horizontal radius.
radiusYdouble100.0Vertical radius.
startAngledouble0.0Starting angle for the 1st item. Anticlockwise with 0° on the right.
endAngledouble360.0Ending angle for the 1st item. Anticlockwise with 0° on the right.

GridShapeParams

NameTypeDefaultsDescription
columnsint3Number of columns.
columnsSpaceHint0Horizontal space between items.
columnsSpaceVint0Vertical space between items.

BackgroundParams

NameTypeDefaultsDescription
animatedBlurboolfalseAnimate background blur from 0.0 to sigma if true.
sigmaXdouble0.0Horizontal blur.
sigmaYdouble0.0Vertical blur.
animatedBackgroundColorboolfalseAnimate backgroundColor from transparent if true.
backgroundColorColor#80000000Background color.

Libraries

star_menu