Bubble

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

Bubble

Example

See sources.

Usage

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

Bubble

- nip

Bubble(
  nip: BubbleNip.TOP_RIGHT,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  nip: BubbleNip.TOP_LEFT,
  child: Text('Hello, programmer!'),
),

Bubble

- alignment

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  child: Text('Hello, programmer!'),
),

Bubble

- color

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  child: Text('Hello, programmer!'),
),

Bubble

- radius

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  radius: 0,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  radius: 10,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  radius: 0,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  radius: 10,
  child: Text('Hello, programmer!'),
),

Bubble

- nipWidth and nipHeight

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  nipWidth: 8,
  nipHeight: 20,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  nipWidth: 8,
  nipHeight: 20,
  child: Text('Hello, programmer!'),
),

Bubble

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  nipWidth: 30,
  nipHeight: 12,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  nipWidth: 30,
  nipHeight: 12,
  child: Text('Hello, programmer!'),
),

Bubble

- nipRadius

for (var i = 0; i <= 6; i++)
  Bubble(
    margin: BubbleEdges.only(top: 4),
    alignment: Alignment.topRight,
    nip: BubbleNip.TOP_RIGHT,
    nipWidth: 30,
    nipHeight: 12,
    nipRadius: i.toDouble(),
    color: Color.fromARGB(255, 225, 255, 199),
    child: Text('Hello, world!'),
  ),
for (var i = 0; i <= 6; i++)
  Bubble(
    margin: BubbleEdges.only(top: 4),
    alignment: Alignment.topLeft,
    nip: BubbleNip.TOP_LEFT,
    nipWidth: 30,
    nipHeight: 12,
    nipRadius: i.toDouble(),
    child: Text('Hello, programmer!'),
  ),

Bubble

Scheme:

Bubble

- nipOffset

for (var i = 0; i <= 6; i++)
  Bubble(
    margin: BubbleEdges.only(top: 4),
    alignment: Alignment.topRight,
    nip: BubbleNip.TOP_RIGHT,
    nipWidth: 30,
    nipHeight: 12,
    nipRadius: i.toDouble(),
    nipOffset: 8,
    color: Color.fromARGB(255, 225, 255, 199),
    child: Text('Hello, world!'),
  ),
for (var i = 0; i <= 6; i++)
  Bubble(
    margin: BubbleEdges.only(top: 4),
    alignment: Alignment.topLeft,
    nip: BubbleNip.TOP_LEFT,
    nipWidth: 30,
    nipHeight: 12,
    nipRadius: i.toDouble(),
    nipOffset: 8,
    child: Text('Hello, programmer!'),
  ),

Bubble

for (var i = 0; i <= 12; i += 3)
  Bubble(
    margin: BubbleEdges.only(top: 4),
    alignment: Alignment.topRight,
    nip: BubbleNip.TOP_RIGHT,
    nipOffset: i.toDouble(),
    color: Color.fromARGB(255, 225, 255, 199),
    child: Text('Hello, world!'),
  ),
for (var i = 0; i <= 12; i += 3)
  Bubble(
    margin: BubbleEdges.only(top: 4),
    alignment: Alignment.topLeft,
    nip: BubbleNip.TOP_LEFT,
    nipOffset: i.toDouble(),
    child: Text('Hello, programmer!'),
  ),

Bubble

- showNip

Add second bubble to everyone.

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 2),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('How are you?'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 2),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  child: Text('And how are you?'),
),

Bubble

Second, third et al bubbles in WhatsApp haven't nips. Remove them.

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 2),
  alignment: Alignment.topRight,
  //nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('How are you?'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 2),
  alignment: Alignment.topLeft,
  //nip: BubbleNip.TOP_LEFT,
  child: Text('And how are you?'),
),

Bubble

It's not that. Hide nips!

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 2),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  showNip: false,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('How are you?'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 2),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  showNip: false,
  child: Text('And how are you?'),
),

Bubble

It's ok :)

- elevation

A thick shadow.

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

Bubble

A thin shadow.

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

...
Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  elevation: 0,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  elevation: 0.5 * px,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  elevation: 1 * px,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  elevation: 1,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  elevation: 0,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  elevation: 0.5 * px,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  elevation: 1 * px,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  elevation: 1,
  child: Text('Hello, programmer!'),
),

Bubble

- shadowColor

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  elevation: 2,
  shadowColor: Colors.red,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  elevation: 2,
  shadowColor: Colors.green,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  elevation: 2,
  shadowColor: Colors.blue,
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  elevation: 2,
  shadowColor: Colors.red,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  elevation: 2,
  shadowColor: Colors.green,
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  elevation: 2,
  shadowColor: Colors.blue,
  child: Text('Hello, programmer!'),
),

Bubble

- margin

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world!'
    'Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  child: Text('Hello, programmer! Hello, programmer! Hello, programmer! Hello, programmer! '
    'Hello, programmer! Hello, programmer! Hello, programmer! Hello, programmer!'),
),

Bubble

Bubble(
  margin: BubbleEdges.only(left: 50),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  child: Text('Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world!'
    'Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10, right: 50),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  child: Text('Hello, programmer! Hello, programmer! Hello, programmer! Hello, programmer! '
    'Hello, programmer! Hello, programmer! Hello, programmer! Hello, programmer!'),
),

Bubble

- padding

Bubble(
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  padding: BubbleEdges.all(2),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  padding: BubbleEdges.all(2),
  child: Text('Hello, programmer!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topRight,
  nip: BubbleNip.TOP_RIGHT,
  color: Color.fromARGB(255, 225, 255, 199),
  padding: BubbleEdges.all(20),
  child: Text('Hello, world!'),
),
Bubble(
  margin: BubbleEdges.only(top: 10),
  alignment: Alignment.topLeft,
  nip: BubbleNip.TOP_LEFT,
  padding: BubbleEdges.all(20),
  child: Text('Hello, programmer!'),
),

Bubble

GitHub

https://github.com/vi-k/bubble