A Flutter widget for chat like a speech bubble in Whatsapp and others

Related tags

Widgets bubble
Overview

Bubble

Pub GitHub stars

A Flutter widget for chat like a speech bubble in Whatsapp and others.

Example

See sources.

Usage

Bubble(
  child: Text('Hello, World!'),
),

• color

Bubble(
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TODAY', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  child: Text('Hi, developer!'),
),

• nip

Bubble(
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TODAY', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  nip: BubbleNip.rightBottom,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  nip: BubbleNip.leftBottom,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  nip: BubbleNip.no,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TOMORROW', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),

• stick

If stick set to false the right offset of bubble equal to the offset from the left, not taking into account the size of the nip. This allows the bubbles to line up. If stick set to true, the far side will be stick to the edge.

Bubble(
  stick: true,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TODAY', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  stick: true,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  stick: true,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  stick: true,
  nip: BubbleNip.rightBottom,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  stick: true,
  nip: BubbleNip.leftBottom,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  stick: true,
  nip: BubbleNip.no,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TOMORROW', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),

• alignment

Bubble(
  alignment: Alignment.center,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TODAY', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightBottom,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftBottom,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.center,
  nip: BubbleNip.no,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TOMORROW', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),

• nipWidth and nipHeight

Bubble(
  alignment: Alignment.center,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TODAY', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nipWidth: 8,
  nipHeight: 24,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nipWidth: 8,
  nipHeight: 24,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nipWidth: 30,
  nipHeight: 10,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nipWidth: 30,
  nipHeight: 10,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.center,
  nip: BubbleNip.no,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TOMORROW', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),

• radius

Bubble(
  alignment: Alignment.center,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TODAY', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  radius: Radius.zero,
  alignment: Alignment.topRight,
  nipWidth: 8,
  nipHeight: 24,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  radius: Radius.zero,
  alignment: Alignment.topLeft,
  nipWidth: 8,
  nipHeight: 24,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  radius: Radius.elliptical(5.0, 10.0),
  alignment: Alignment.topRight,
  nipWidth: 30,
  nipHeight: 10,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  radius: Radius.elliptical(5.0, 10.0),
  alignment: Alignment.topLeft,
  nipWidth: 30,
  nipHeight: 10,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  radius: Radius.circular(20.0),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  radius: Radius.circular(20.0),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.center,
  nip: BubbleNip.no,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TOMORROW', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),

• nipRadius

for (var i = 0; i <= 5; i++)
  Bubble(
    margin: BubbleEdges.only(top: 10),
    nipRadius: i.toDouble(),
    alignment: Alignment.topRight,
    nipWidth: 30,
    nipHeight: 10,
    nip: BubbleNip.rightTop,
    color: Color.fromRGBO(225, 255, 199, 1.0),
    child: Text('Hello, World!', textAlign: TextAlign.right),
  ),
for (var i = 0; i <= 5; i++)
  Bubble(
    margin: BubbleEdges.only(top: 10),
    nipRadius: i.toDouble(),
    alignment: Alignment.topLeft,
    nipWidth: 30,
    nipHeight: 10,
    nip: BubbleNip.leftTop,
    child: Text('Hi, developer!'),
  ),

Scheme:

Bubble

• nipOffset

for (var i = 0; i <= 15; i += 3)
  Bubble(
    margin: BubbleEdges.only(top: 10),
    nipOffset: i.toDouble(),
    alignment: Alignment.topRight,
    nipWidth: 30,
    nipHeight: 10,
    nip: BubbleNip.rightTop,
    color: Color.fromRGBO(225, 255, 199, 1.0),
    child: Text('Hello, World!', textAlign: TextAlign.right),
  ),
for (var i = 0; i <= 15; i += 3)
  Bubble(
    margin: BubbleEdges.only(top: 10),
    nipOffset: i.toDouble(),
    alignment: Alignment.topLeft,
    nipWidth: 30,
    nipHeight: 10,
    nip: BubbleNip.leftTop,
    child: Text('Hi, developer!'),
  ),

• margin

Bubble(
  alignment: Alignment.center,
  color: const Color.fromRGBO(212, 234, 244, 1),
  child: const Text('TODAY',
      textAlign: TextAlign.center,
      style: TextStyle(fontSize: 11)),
),
Bubble(
  margin: const BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: const Color.fromRGBO(225, 255, 199, 1),
  child: const Text('Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: const BubbleEdges.only(top: 2),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  showNip: false,
  color: const Color.fromRGBO(225, 255, 199, 1),
  child: const Text('How are you?', textAlign: TextAlign.right),
),
Bubble(
  margin: const BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: const Text('Hi, developer!'),
),
Bubble(
  margin: const BubbleEdges.only(top: 2),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  showNip: false,
  child: const Text('Well, see for yourself'),
),

Bubble(
  alignment: Alignment.center,
  color: Color.fromRGBO(212, 234, 244, 1.0),
  child: Text('TODAY', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World! Hello, World! Hello, World! Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer! Hi, developer! Hi, developer! Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10, left: 40),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromRGBO(225, 255, 199, 1.0),
  child: Text('Hello, World! Hello, World! Hello, World! Hello, World!', textAlign: TextAlign.right),
),
Bubble(
  margin: BubbleEdges.only(top: 10, right: 40),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer! Hi, developer! Hi, developer! Hi, developer!'),
),

• elevation

A thick shadow.

for (var i = 1; i <= 8; i *= 2)
  Column(
    children: <Widget>[
      Bubble(
        margin: BubbleEdges.only(top: 10),
        elevation: i.toDouble(),
        alignment: Alignment.topRight,
        nip: BubbleNip.rightTop,
        color: Color.fromARGB(255, 225, 255, 199),
        child: Text('Hello, World!'),
      ),
      Bubble(
        margin: BubbleEdges.only(top: 10),
        elevation: i.toDouble(),
        alignment: Alignment.topLeft,
        nip: BubbleNip.leftTop,
        child: Text('Hi, developer!'),
      ),
    ],
  ),

A thin shadow.

double px = 1 / MediaQuery.of(context).devicePixelRatio;

...

Bubble(
  elevation: 0,
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  elevation: 0.5 * px,
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  elevation: 1 * px,
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  elevation: 1,
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  elevation: 0,
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  elevation: 0.5 * px,
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  elevation: 1 * px,
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  elevation: 1,
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),

• shadowColor

Bubble(
  shadowColor: Colors.red,
  elevation: 2,
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  shadowColor: Colors.green,
  elevation: 2,
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  shadowColor: Colors.blue,
  elevation: 2,
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  shadowColor: Colors.red,
  elevation: 2,
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  shadowColor: Colors.green,
  elevation: 2,
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  shadowColor: Colors.blue,
  elevation: 2,
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),

• padding

Bubble(
  padding: BubbleEdges.all(2),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  padding: BubbleEdges.all(2),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  padding: BubbleEdges.all(20),
  alignment: Alignment.topRight,
  nip: BubbleNip.rightTop,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, World!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  padding: BubbleEdges.all(20),
  alignment: Alignment.topLeft,
  nip: BubbleNip.leftTop,
  child: Text('Hi, developer!'),
),

Comments
  • Nip draw in wrong position

    Nip draw in wrong position

    i am using the following code to add bubbles to the screen:

    class ChatMessageWidget extends StatelessWidget { final bool self; final String text; final AnimationController animationController;

    ChatMessageWidget({this.text,this.animationController,this.self});

    TextStyle _msgStyle = TextStyle( color: Palette.blackColor, fontSize: 15, fontFamily: "Lato", fontWeight: FontWeight.w500, );

    @override Widget build(BuildContext context) { print("Message widget build self = $self $text"); return SizeTransition( sizeFactor: CurvedAnimation( parent: animationController, curve: Curves.easeOut ), axisAlignment: 0.0, child: Container( margin: const EdgeInsets.symmetric(vertical: 10.0), child: Row( mainAxisAlignment: self == true ? MainAxisAlignment.start : MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.start, children: [ Bubble( color: self == true ? Colors.white : Color.fromRGBO(225, 255, 199, 1.0), //margin: BubbleEdges.only(top: 5), nip: self == true ? BubbleNip.leftTop : BubbleNip.rightTop, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: const EdgeInsets.only(top: 5.0), child: Text(text,style: _msgStyle,), ), ], ), ), ], ), ), ); } }

    after adding new message the nips are getting drawn in the wrong position, however the position and color are correct (please see screen shots), if i drag the bubbles out of the screen (so they need to get redrow) the nip is in the correct position

    Simulator Screen Shot - iPhone 8 - 2020-04-17 at 11 06 00 Simulator Screen Shot - iPhone 8 - 2020-04-17 at 11 06 24

    bug 
    opened by pazhut 6
  • Massive reduce on performance when bubble nip is visible

    Massive reduce on performance when bubble nip is visible

                ListView.builder(
                  itemCount: 1000,
                  itemBuilder: (BuildContext context, int index) {
                    return Bubble(
                      nip: BubbleNip.rightTop,
                      child: Text('TEST MESSAGE BODY #$index'),
                    );
                  },      
    
    opened by ahmedNY 6
  • [feat] Add onTap & onLongPress callback

    [feat] Add onTap & onLongPress callback

    Looks great to implement onTap & onLongPress to handle click action.

    For example:

    Bubble(
      onTap: () {
        print('Hello from onTap');
      },
      onLongPress: () {
        print('Hello from onLongPress');
      },
      // .. other properties
    ),
    
    opened by hsul4n 3
  • Layout in iOS is invalid ?

    Layout in iOS is invalid ?

    Hi,

    i'm face this issue, when use install from app store, it's show large grey block. is there anything i doing worng?

    -> simulator , UI is good -> plug-in device install , UI is good -> archive and release to app Store, UI is wrong.

    Anyone help, please?

    [✓] Flutter (Channel master, v1.15.4-pre.139, on Mac OS X 10.14.6 18G87, locale zh-Hant-TW) • Flutter version 1.15.4-pre.139 at /Users/jason/flutter • Framework revision 4df8fdb7df (2 days ago), 2020-02-22 18:24:03 -0800 • Engine revision f2f8c342be • Dart version 2.8.0 (build 2.8.0-dev.9.0 0f141be8bd)

        Flexible( 
              child: InkWell(
                  onTap: () => messageClickEvent(msg),
                  onLongPress: () => _showMessageMenu(context, index),
                  child: RoomMgr.instance().isMessageSticker(msg) ||
                          RoomMgr.instance().isMessagePhoto(msg) ||
                          RoomMgr.instance().isMessageLocalPhoto(msg)
                      ? Container(
                          padding: EdgeInsets.fromLTRB(4, 4, 4, 4),
                          constraints: BoxConstraints(maxWidth: 200),
                          child: getGraphicMessageWidget(msg))
                      : Bubble(
                          margin: BubbleEdges.only(top: 10),
                          nip: BubbleNip.rightBottom,
                          color: Color.fromRGBO(225, 255, 199, 1.0),
                          child: Text('${msg.content}', textAlign: TextAlign.left),
                        )),
            )
    

    flutter doctor -v

    [✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
        • Android SDK at /Users/jason/Library/Android/sdk
        • Android NDK location not configured (optional; useful for native profiling support)
        • Platform android-29, build-tools 28.0.3
        • ANDROID_HOME = /Users/jason/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Xcode 11.3.1, Build version 11C504
        • CocoaPods version 1.8.4
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 3.5)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin version 43.0.1
        • Dart plugin version 191.8593
        • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    
    [✓] VS Code (version 1.42.1)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.8.1
    
    [✓] Connected device (4 available)
        • iPhone 11 Pro Max • 1CF9A7D0-45B9-455F-BC83-4B722F8247D3 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)
        • macOS             • macOS                                • darwin-x64     • Mac OS X 10.14.6 18G87
        • Chrome            • chrome                               • web-javascript • Google Chrome 80.0.3987.122
        • Web Server        • web-server                           • web-javascript • Flutter Tools
    
    • No issues found!
    

    Normal UI normal

    After submit app store after-sumbit-app-store

    opened by jasoncheng 3
  • Add custom key

    Add custom key

    Hi! I'm using GetX with a ListView.builder to add a list of bubble messages in realtime. However, when Getx rebuild ListView, some "Bubble's widget" are not refreshing and lose its nip (it changes nip direction). However, I did a temporal fix adding a UniqueKey() on a parent container, just like this:

    return Container(
          key: UniqueKey(),
          child: Bubble(
              ...
            ),
          ),
        )
    

    Right now, that works like a charm. So, can you add a "key" parameter? Thanks u!

    opened by facuparedes 2
  • UnimplementedError on web when running example

    UnimplementedError on web when running example

    Running the example mentioned in pub.dev for bubble causes an UnimplementedError on web with the following stacktrace:

    logs
    ======== Exception caught by rendering library =====================================================
    UnimplementedError
    The relevant error-causing widget was: 
      CustomPaint file:///C:/Users/Mehul/flutter/.pub-cache/hosted/pub.dartlang.org/bubble-1.2.1/lib/bubble.dart:92:16
    ====================================================================================================
    
    ======== Exception caught by rendering library =====================================================
    UnimplementedError
    The relevant error-causing widget was: 
      PhysicalShape file:///C:/Users/Mehul/GithubProjects/flutter_app/lib/main.dart:156:11
    The following RenderObject was being processed when the exception was fired: RenderPhysicalShape#648ff relayoutBoundary=up5
      needs compositing
      parentData: <none> (can use size)
      constraints: BoxConstraints(w=913.0, 0.0<=h<=Infinity)
      size: Size(913.0, 40.0)
      elevation: 2.0
      color: Color(0x408bc34a)
      shadowColor: Color(0x408bc34a)
      clipper: IssueClipper
      child: RenderConstrainedBox#310d5 relayoutBoundary=up6 NEEDS-PAINT
        parentData: <none> (can use size)
        constraints: BoxConstraints(w=913.0, 0.0<=h<=Infinity)
        size: Size(913.0, 40.0)
        additionalConstraints: BoxConstraints(w=80.0, h=40.0)
    RenderObject: RenderPhysicalShape#648ff relayoutBoundary=up5
      needs compositing
      parentData: <none> (can use size)
      constraints: BoxConstraints(w=913.0, 0.0<=h<=Infinity)
      size: Size(913.0, 40.0)
      elevation: 2.0
      color: Color(0x408bc34a)
      shadowColor: Color(0x408bc34a)
      clipper: IssueClipper
      child: RenderConstrainedBox#310d5 relayoutBoundary=up6 NEEDS-PAINT
        parentData: <none> (can use size)
        constraints: BoxConstraints(w=913.0, 0.0<=h<=Infinity)
        size: Size(913.0, 40.0)
        additionalConstraints: BoxConstraints(w=80.0, h=40.0)
    ====================================================================================================
    
    ======== Exception caught by rendering library =====================================================
    UnimplementedError
    The relevant error-causing widget was: 
      PhysicalShape file:///C:/Users/Mehul/GithubProjects/flutter_app/lib/main.dart:164:11
    The following RenderObject was being processed when the exception was fired: RenderPhysicalShape#42f40 relayoutBoundary=up5
      needs compositing
      parentData: <none> (can use size)
      constraints: BoxConstraints(w=913.0, 0.0<=h<=Infinity)
      size: Size(913.0, 40.0)
      elevation: 2.0
      color: Color(0x408bc34a)
      shadowColor: Color(0x408bc34a)
      clipper: IssueClipper
      child: RenderConstrainedBox#4e688 relayoutBoundary=up6 NEEDS-PAINT
        parentData: <none> (can use size)
        constraints: BoxConstraints(w=913.0, 0.0<=h<=Infinity)
        size: Size(913.0, 40.0)
        additionalConstraints: BoxConstraints(w=80.0, h=40.0)
    RenderObject: RenderPhysicalShape#42f40 relayoutBoundary=up5
      needs compositing
      parentData: <none> (can use size)
      constraints: BoxConstraints(w=913.0, 0.0<=h<=Infinity)
      size: Size(913.0, 40.0)
      elevation: 2.0
      color: Color(0x408bc34a)
      shadowColor: Color(0x408bc34a)
      clipper: IssueClipper
      child: RenderConstrainedBox#4e688 relayoutBoundary=up6 NEEDS-PAINT
        parentData: <none> (can use size)
        constraints: BoxConstraints(w=913.0, 0.0<=h<=Infinity)
        size: Size(913.0, 40.0)
        additionalConstraints: BoxConstraints(w=80.0, h=40.0)
    ====================================================================================================
    
    

    Tested on flutter's master, dev and beta channel

    opened by Silver-Fullbuster 1
  • Add icon to end of Bubble widget

    Add icon to end of Bubble widget

    I want to add an indicator icon to the end of bubble widget for users to know if their message has been sent, is Pending or read just like what's app. There seems to be no provision for this. Any help?

    opened by benthemobileguy 1
  • How to show html tag

    How to show html tag

    Hi admin,

    I have a string html: <img src="https://www.w3schools.com/howto/img_avatar.png">

    I want the image to display in a moderate size, not width 100%.

    opened by thanhansoft 1
  • Add reaction support

    Add reaction support

    Hi. first of all thanks for the good work. It will be great if bubble support the reaction feature. an emoji located at the bottom of the message like telegram. Thanks

    image

    opened by jefcolbi 0
  • UnimplementedError on web with --web-renderer html

    UnimplementedError on web with --web-renderer html

    I get UnimplementedError with the following stack trace when trying to show a bubble with HTML renderer for Flutter web:

    dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49  throw_
    lib/ui/src/ui/path.dart 72:5                                                  combine
    packages/bubble/bubble_clipper.dart 195:23                                    getClip
    packages/bubble/bubble_painter.dart 35:26                                     paint
    packages/flutter/src/rendering/custom_paint.dart 563:12                       [_paintWithPainter]
    packages/flutter/src/rendering/custom_paint.dart 605:7                        paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/shifted_box.dart 79:14                         paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/shifted_box.dart 79:14                         paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/shifted_box.dart 79:14                         paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/shifted_box.dart 79:14                         paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 398:12                             pushLayer
    packages/visibility_detector/src/render_visibility_detector.dart 64:12        paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 141:10                             _repaintCompositedChild
    packages/flutter/src/rendering/object.dart 100:5                              repaintCompositedChild
    packages/flutter/src/rendering/object.dart 206:7                              [_compositeChild]
    packages/flutter/src/rendering/object.dart 187:7                              paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/sliver_multi_box_adaptor.dart 647:16           paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/sliver_padding.dart 274:14                     paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/viewport.dart 660:16                           [_paintContents]
    packages/flutter/src/rendering/object.dart 398:12                             pushLayer
    packages/flutter/src/rendering/object.dart 454:7                              pushClipRect
    packages/flutter/src/rendering/viewport.dart 635:37                           paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 141:10                             _repaintCompositedChild
    packages/flutter/src/rendering/object.dart 100:5                              repaintCompositedChild
    packages/flutter/src/rendering/object.dart 206:7                              [_compositeChild]
    packages/flutter/src/rendering/object.dart 187:7                              paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 141:10                             _repaintCompositedChild
    packages/flutter/src/rendering/object.dart 100:5                              repaintCompositedChild
    packages/flutter/src/rendering/object.dart 206:7                              [_compositeChild]
    packages/flutter/src/rendering/object.dart 187:7                              paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/custom_paint.dart 608:11                       paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 141:10                             _repaintCompositedChild
    packages/flutter/src/rendering/object.dart 100:5                              repaintCompositedChild
    packages/flutter/src/rendering/object.dart 206:7                              [_compositeChild]
    packages/flutter/src/rendering/object.dart 187:7                              paintChild
    packages/flutter/src/rendering/box.dart 2794:14                               defaultPaint
    packages/flutter/src/rendering/stack.dart 629:5                               paintStack
    packages/flutter/src/rendering/stack.dart 645:7                               paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/box.dart 2794:14                               defaultPaint
    packages/flutter/src/rendering/flex.dart 1078:7                               paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/box.dart 2794:14                               defaultPaint
    packages/flutter/src/rendering/stack.dart 629:5                               paintStack
    packages/flutter/src/rendering/stack.dart 645:7                               paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/box.dart 2794:14                               defaultPaint
    packages/flutter/src/rendering/flex.dart 1078:7                               paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/stack.dart 744:12                              paintStack
    packages/flutter/src/rendering/stack.dart 645:7                               paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/box.dart 2794:14                               defaultPaint
    packages/flutter/src/rendering/flex.dart 1078:7                               paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/stack.dart 744:12                              paintStack
    packages/flutter/src/rendering/stack.dart 645:7                               paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/box.dart 2794:14                               defaultPaint
    packages/flutter/src/rendering/custom_layout.dart 409:5                       paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/material/material.dart 553:11                            paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 398:12                             pushLayer
    packages/flutter/src/rendering/proxy_box.dart 1941:14                         paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/shifted_box.dart 79:14                         paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 189:12                             paintChild
    packages/flutter/src/rendering/proxy_box.dart 140:14                          paint
    packages/flutter/src/rendering/object.dart 2409:7                             [_paintWithContext]
    packages/flutter/src/rendering/object.dart 141:10                             _repaintCompositedChild
    packages/flutter/src/rendering/object.dart 100:5                              repaintCompositedChild
    packages/flutter/src/rendering/object.dart 979:29                             flushPaint
    packages/flutter/src/rendering/binding.dart 455:19                            drawFrame
    packages/flutter/src/widgets/binding.dart 883:13                              drawFrame
    packages/flutter/src/rendering/binding.dart 319:5                             [_handlePersistentFrameCallback]
    packages/flutter/src/scheduler/binding.dart 1143:15                           [_invokeFrameCallback]
    packages/flutter/src/scheduler/binding.dart 1080:9                            handleDrawFrame
    packages/flutter/src/scheduler/binding.dart 996:5                             [_handleDrawFrame]
    lib/_engine/engine/platform_dispatcher.dart 1003:13                           invoke
    lib/_engine/engine/platform_dispatcher.dart 157:5                             invokeOnDrawFrame
    lib/_engine/engine.dart 440:45                                                <fn>
    

    I tested for BubbleNip.leftBottom. What's breaking is

    path = Path.combine(PathOperation.union, path, path2);
    

    This is a Flutter issue: https://github.com/flutter/flutter/issues/44572 It is there for nearly two years, dropped out of many milestones and currently has none.

    What could be done here is either:

    1. To create paths without combining.
    2. Or at least to mention the CanvasKit requirement in README.
    opened by alexeyinkin 1
  • Dynamic list of bubbles

    Dynamic list of bubbles

    Hello,

    I have the following code to implement a dynamic list of chat bubbles. The issue is that in the setState the bubbles are not redrawn. Could you please provide an example of dynamically generating bubbles.

    Also, how do I autoscroll to the bottom that new bubbles are added?

    Thank you.

    List<Widget> bubbles = <Widget>[];
    
    void onSomeEvent() {
        setState(() {
            bubbles.add(new Bubble(color: Colors.blue, child: new Text('Hello Bubble');
        }
    }
    
    @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Quantum AI Scribe"),
          ),
          body: Container(
            color: Colors.black12,
            child: ListView(
              padding: const EdgeInsets.all(8),
              children: bubbles,
            ),
          )
        );
     }
    
    opened by dweberlj 0
Owner
Victor Dunaev
Victor Dunaev
A Flutter library to add the Common effect (line, bubble, dot ...) of tab indicator.

flutter_tab_indicator A Flutter library to add the Common effect (line, bubble, dot ...) of tab indicator. Showcases Installation Showcases Showcases

CrabMan 14 Jun 19, 2022
A Flutter widget for Tinder like swipe cards

A Flutter widget for Tinder like swipe cards. The card can be swiped right, left and up for different responses

Abdul Basit 7 Nov 2, 2022
This repo is for anything that can be reusable in flutter like custom widgets 🟥, animations 🌟and more

Flutter Shortcuts This repo is for anything that can be reusable in flutter like custom widgets ?? , animations ?? and more. How to Use Just get the f

Abdelrahman Mostafa Elmarakby 91 Dec 3, 2022
Donation/Support buttons to allow you to add your favorite support buttons like: Paypal, Ko-fi or Patreon and more.

flutter_donation_buttons Donation/Support buttons to allow you to add your favorite support buttons like: Paypal, Ko-fi or Patreon and more. Getting S

null 6 Dec 10, 2022
A basic Flutter app that includes some native Widgets like alerts, cards, avatars, animated container, inputs, etc.

Flutter components This project was created with Flutter and some native Widgets like alerts, cards, avatars, animated container, inputs, etc. Getting

Paúl 4 Nov 15, 2021
pull_down_button is a rework of Flutter's PopupMenuButton to be styled like Pop-Up & Pull-Down Buttons from iOS 14+ with some additional customisation options.

pull_down_button is a rework of Flutter's PopupMenuButton to be styled like Pop-Up & Pull-Down Buttons from iOS 14+ with some additional customisation options.

ĐmĐrl 18 Dec 30, 2022
A flutter carousel widget, support infinite scroll, and custom child widget.

carousel_slider A carousel slider widget. Features Infinite scroll Custom child widgets Auto play Supported platforms Flutter Android Flutter iOS Flut

Bart T 1 Nov 25, 2021
Progress Dialog widget for flutter projects with ability to customize loading widget, background color and background blur.

DISCONTINUED Checkout ArsDialog ars_progress_dialog Customizable progress dialog for Flutter applications with smooth animation for background dim col

Arsam 8 Apr 15, 2022
iOS-like proof of concept reorderable list with animations

Reorderable List in Flutter iOS-like proof of concept reorderable list with animations Preview Getting Started See example/lib/main.dart for example u

Matej Knopp 304 Jan 2, 2023
A Facebook & Twitter Like Card Loading Shimmer Skeleton Library.

PKSkeleton A Facebook & Twitter Like Card Loading Shimmer Skeleton Library. The source code is 100% Dart, and everything resides in the /lib folder. S

Pawan Kumar 283 Nov 26, 2022
A button that looks like a Cupertino text button

Cupertino Text Button A button that looks like a Cupertino text button! Text Button A simple text button can be created like this: CupertinoTextButton

Nick Sirovsky 0 Nov 24, 2022
Experimental solution for web-like text selection across widgets

Better Selection Experimental solution for web-like text selection across widgets (text, images, et cetera). Better selection is dependent on, and is

Wilson Wilson 59 Oct 12, 2022
A simple Flutter widget to add in the widget tree when you want to show nothing, with minimal impact on performance.

nil A simple widget to add in the widget tree when you want to show nothing, with minimal impact on performance. Why? Sometimes, according to a condit

Romain Rastel 127 Dec 22, 2022
A Flutter Widget to make interactive timeline widget.

Bubble Timeline Package A Flutter Widget to make interactive timeline widget. This widget can be used to make Event Timelines, or Timelines for certai

Vansh Goel 12 Sep 22, 2022
📸 Easy to use yet very customizable zoomable image widget for Flutter, Photo View provides a gesture sensitive zoomable widget.

?? Easy to use yet very customizable zoomable image widget for Flutter, Photo View provides a gesture sensitive zoomable widget. Photo View is largely used to show interacive images and other stuff such as SVG.

Blue Fire 1.7k Jan 7, 2023
A widget lib that the widget in this lib can react to flutter ScrollController's offset

Language: English | 中文简体 linked_scroll_widgets A lib full of widgets that can react to the scrollController's offset change,to custom your UI effect.

WenJingRui 8 Oct 16, 2022
Full customable rolling switch widget for flutter apps based on Pedro Massango's 'crazy-switch' widget

lite_rolling_switch Full customable rolling switch widget for flutter apps based on Pedro Massango's 'crazy-switch' widget https://github.com/pedromas

Eduardo Muñoz 48 Dec 1, 2022
A Flutter widget that will give a Glitch Animation Effect to it's child widget.

GlitchEffect A Flutter widget that will give a Glitch Animation Effect to it's child widget. Installation Add the latest version of package to your pu

Sameer Singh 6 Nov 25, 2022
Widget, that can make any static located widget hidable

Installing See the official installing guidline from hidable/install Usage & Overview To start using Hidable widget, we have to create a ScrollControl

Anon 18 Dec 16, 2022