Flutter open popup menu above list item

I am making a chat app in Flutter with Firestore but I am stumped with one of the requirement: Making a reaction menu appear above a chat dialog. I need that when the user long press on a chat text the reaction menu would appear above the current chat position. Something like Facebook Messenger app:

enter image description here

I have look around and found https://medium.com/@duytq94/facebook-reactions-with-flutter-9019ce8b95b8 but it seems it is too much for just a simple function (making a popup menu appear above a list tile and don't need the animation). I also found this package: https://pub.dev/packages/flutter_reaction_button, but it does not allow to wrap the widget around another to open up the reacton menu. Is there a simple way that I can archive this? I have looked into PopupMenuButton but it only allows onPressed and not long press.

Upvotes: 0

Views: 3356

Answers (1)

devyl
devyl

Reputation: 121

You can use Overlay widget. I make a simple example for you.

import 'package:flutter/material.dart';

class Temp extends StatefulWidget {
  @override
  _TempState createState() => _TempState();
}

class _TempState extends State<Temp> {
  GlobalKey floatingKey = LabeledGlobalKey("Floating");
  bool isFloatingOpen = false;
  OverlayEntry floating;

  OverlayEntry createFloating() {
    RenderBox renderBox = floatingKey.currentContext.findRenderObject();
    Offset offset = renderBox.localToGlobal(Offset.zero);
    return OverlayEntry(
      builder: (context) {
        return Positioned(
          left: offset.dx,
          width: renderBox.size.width,
          top: offset.dy - 50,
          child: Material(
            elevation: 20,
            child: Container(
              height: 50,
              color: Colors.blue,
              child: Text("I'm floating overlay")
            )
          )
        );
      }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          key: floatingKey,
          color: Colors.red,
          onPressed: (){
            setState(() {
              if(isFloatingOpen) floating.remove();
              else {
                floating = createFloating();
                Overlay.of(context).insert(floating);
              }
              isFloatingOpen = !isFloatingOpen;
            });
          },
        )
      ),
    );
  }
}

Upvotes: 1

Related Questions