dots_menu 1.0.3 copy "dots_menu: ^1.0.3" to clipboard
dots_menu: ^1.0.3 copied to clipboard

A customizable, animated Flutter widget that provides a modern dots menu for contextual actions. Easily integrates into your app, supports both horizontal and vertical layouts, and allows for flexible [...]

example/lib/main.dart

import 'package:flutter/material.dart';

import 'package:dots_menu/dots_menu.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dots menu example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const Scaffold(body: MyHomePage(title: 'Flutter Demo Home Page')),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return const Material(
      child: SingleChildScrollView(
        child: Center(
          child: Column(
            children: [
              SizedBox(height: 64),
              VerticalExample(),
              SizedBox(height: 64 * 2),
              HorizontalExample(),
              SizedBox(height: 64 * 2),
              TenExample(),
              SizedBox(height: 64),
            ],
          ),
        ),
      ),
    );
  }
}

class VerticalExample extends StatefulWidget {
  const VerticalExample({super.key});

  @override
  State<VerticalExample> createState() => _VerticalExampleState();
}

class _VerticalExampleState extends State<VerticalExample> {
  var expanded = false;

  void setStateExpanded(bool v) {
    setState(() {
      expanded = v;
    });
  }

  late final items2 = [
    DotsMenuIcon(
      backgroudColor: Colors.blue.shade100,
      child: const Icon(size: 18, Icons.edit),
      onTap: () {
        ScaffoldMessenger.of(context).showMaterialBanner(
          MaterialBanner(
            content: const Text('Edit!'),
            actions: [IconButton(onPressed: () {}, icon: const Text('x'))],
          ),
        );
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      backgroudColor: Colors.red.shade100,
      child: const Icon(size: 18, Icons.delete, color: Colors.red),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Deleted!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.close_rounded),
      onTap: () => setStateExpanded(false),
    ),
    // DotsMenuIcon(
    //   child: const Icon(
    //     size: 32,
    //     Icons.icecream,
    //   ),
    //   onTap: () => setStateExpanded(false),
    // ),
    // DotsMenuIcon(
    //   child: const Icon(
    //     Icons.money,
    //   ),
    //   onTap: () => setStateExpanded(false),
    // ),
  ];

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        const Text('Vertical'),
        const SizedBox(height: 24),
        Center(
          child: DotsMenu(
            expanded: expanded,
            direction: Axis.vertical,
            onTap: () => setStateExpanded(true),
            items: items2,
          ),
        ),
      ],
    );
  }
}

class HorizontalExample extends StatefulWidget {
  const HorizontalExample({super.key});

  @override
  State<HorizontalExample> createState() => _HorizontalExampleState();
}

class _HorizontalExampleState extends State<HorizontalExample> {
  var expanded = false;

  void setStateExpanded(bool v) {
    setState(() {
      expanded = v;
    });
  }

  late final items2 = [
    DotsMenuIcon(
      backgroudColor: Colors.blue.shade100,
      child: const Icon(size: 18, Icons.edit),
      onTap: () {
        ScaffoldMessenger.of(context).showMaterialBanner(
          MaterialBanner(
            content: const Text('Edit!'),
            actions: [IconButton(onPressed: () {}, icon: const Text('x'))],
          ),
        );
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      backgroudColor: Colors.red.shade100,
      child: const Icon(size: 18, Icons.delete, color: Colors.red),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Deleted!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.close_rounded),
      onTap: () => setStateExpanded(false),
    ),
    // DotsMenuIcon(
    //   child: const Icon(
    //     size: 32,
    //     Icons.icecream,
    //   ),
    //   onTap: () => setStateExpanded(false),
    // ),
    // DotsMenuIcon(
    //   child: const Icon(
    //     Icons.money,
    //   ),
    //   onTap: () => setStateExpanded(false),
    // ),
  ];

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        const Text('Horizontal'),
        const SizedBox(height: 24),
        Center(
          child: DotsMenu(
            expanded: expanded,
            direction: Axis.horizontal,
            onTap: () => setStateExpanded(true),
            items: items2,
          ),
        ),
      ],
    );
  }
}

class TenExample extends StatefulWidget {
  const TenExample({super.key});

  @override
  State<TenExample> createState() => _TenExampleState();
}

class _TenExampleState extends State<TenExample> {
  var expanded = false;

  void setStateExpanded(bool v) {
    setState(() {
      expanded = v;
    });
  }

  late final items2 = [
    DotsMenuIcon(
      backgroudColor: Colors.blue.shade100,
      child: const Icon(size: 18, Icons.edit),
      onTap: () {
        ScaffoldMessenger.of(context).showMaterialBanner(
          MaterialBanner(
            content: const Text('Edit!'),
            actions: [IconButton(onPressed: () {}, icon: const Text('x'))],
          ),
        );
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      backgroudColor: Colors.red.shade100,
      child: const Icon(size: 18, Icons.delete, color: Colors.red),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Deleted!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.close_rounded),
      onTap: () => setStateExpanded(false),
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.star, color: Colors.amber),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Starred!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.favorite, color: Colors.pink),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Favorited!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.share, color: Colors.blue),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Shared!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.copy, color: Colors.green),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Copied!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.download, color: Colors.indigo),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Downloaded!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.upload, color: Colors.orange),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Uploaded!')));
        setStateExpanded(false);
      },
    ),
    DotsMenuIcon(
      child: const Icon(size: 18, Icons.settings, color: Colors.grey),
      onTap: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Settings!')));
        setStateExpanded(false);
      },
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        const Text('You can have as many dots as you want!'),
        const SizedBox(height: 24),
        Center(
          child: DotsMenu(
            expanded: expanded,
            direction: Axis.horizontal,
            onTap: () => setStateExpanded(true),
            items: items2,
          ),
        ),
      ],
    );
  }
}
6
likes
125
points
31
downloads

Publisher

verified publisherstatelysoft.com

Weekly Downloads

A customizable, animated Flutter widget that provides a modern dots menu for contextual actions. Easily integrates into your app, supports both horizontal and vertical layouts, and allows for flexible action icons and smooth animations.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on dots_menu