Action Button in Flutter Chat (SfChat)

18 Nov 201822 minutes to read

This section explains how to add and customize the action button using the available options.

Action button

The actionButton represents the send button and is not included in chat by default. To add it, create an instance of ChatActionButton and assign it to the actionButton property.

When the button is pressed, ChatActionButton.onPressed is called. SfChat does not auto-add composed text to the message list, so you must create a ChatMessage and add it manually in the callback.

If ChatComposer.builder is used, the onPressed text argument is always empty. Read the custom text from your controller and append it to the message list manually. For a builder-based composer flow, see Composer.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  State<DefaultActionButtonExample> createState() => _DefaultActionButtonExampleState();
}

class _DefaultActionButtonExampleState extends State<DefaultActionButtonExample> {
  late List<ChatMessage> _messages;

  @override
  void initState() {
    super.initState();
    _messages = <ChatMessage>[
      ChatMessage(
        text: 'Hi!',
        time: DateTime(2024, 08, 07, 9, 0),
        author: const ChatAuthor(id: '123-001', name: 'John Doe'),
      ),
      ChatMessage(
        text: 'Hello! How’s it going?',
        time: DateTime(2024, 08, 07, 9, 5),
        author: const ChatAuthor(id: '123-002', name: 'Jane Smith'),
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Padding(
          padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 100),
          child: SfChat(
            messages: _messages,
            outgoingUser: '123-001',
            actionButton: ChatActionButton(
              onPressed: (String newMessage) {
                if (newMessage.trim().isEmpty) {
                  return;
                }
                setState(() {
                  _messages = <ChatMessage>[
                    ..._messages,
                    ChatMessage(
                      text: newMessage,
                      time: DateTime.now(),
                      author: const ChatAuthor(id: '123-001', name: 'John Doe'),
                    ),
                  ];
                });
              },
            ),
          ),
        ),
      ),
    );
  }
}

Chat actionButton support

Child

The child property allows you to specify interactive content for the button.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: <ChatMessage>[
            ChatMessage(
              text: 'Hi!',
              time: DateTime(2024, 08, 07, 9, 0),
              author: const ChatAuthor(id: '123-001', name: 'John Doe'),
            ),
          ],
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            child: const Icon(Icons.chat, color: Colors.grey, size: 25),
            onPressed: (String _) {},
          ),
        ),
      ),
    );
  }
}

Chat actionButton support

onPressed callback

The onPressed callback is invoked whenever the action button is pressed.

Use this callback to create a new message and rebuild the widget with the updated messages list.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  State<ActionButtonOnPressedExample> createState() => _ActionButtonOnPressedExampleState();
}

class _ActionButtonOnPressedExampleState extends State<ActionButtonOnPressedExample> {
  final List<ChatMessage> _messages = <ChatMessage>[];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: _messages,
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            onPressed: (String newMessage) {
              if (newMessage.trim().isEmpty) {
                return;
              }
              setState(() {
                _messages.add(
                  ChatMessage(
                    text: newMessage,
                    time: DateTime.now(),
                    author: const ChatAuthor(id: '123-001', name: 'John Doe'),
                  ),
                );
              });
            },
          ),
        ),
      ),
    );
  }
}

Tooltip

The tooltip text describes the button action. It appears on long press (touch) or hover (desktop).

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: <ChatMessage>[
            ChatMessage(
              text: 'Hi!',
              time: DateTime(2024, 08, 07, 9, 0),
              author: const ChatAuthor(id: '123-001', name: 'John Doe'),
            ),
          ],
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            tooltip: 'Send message',
            onPressed: (String _) {},
          ),
        ),
      ),
    );
  }
}

Chat actionButton support

Colors

The foregroundColor property defines icon color.

The backgroundColor property defines button background color.

The focusColor, hoverColor, and splashColor properties customize interaction colors.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: const <ChatMessage>[],
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            foregroundColor: Colors.white,
            backgroundColor: Colors.blue,
            focusColor: Theme.of(context).colorScheme.primary.withValues(alpha: 0.86),
            hoverColor: Theme.of(context).colorScheme.primary.withValues(alpha: 0.91),
            splashColor: Colors.white.withValues(alpha: 0.3),
            onPressed: (String _) {},
          ),
        ),
      ),
    );
  }
}

Elevation

The elevation property defines shadow depth when the button is not focused, hovered, or pressed.

The focusElevation property defines elevation while focused.

The hoverElevation property defines elevation while hovered.

The highlightElevation property defines elevation while pressed.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: const <ChatMessage>[],
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            elevation: 2.0,
            focusElevation: 6.0,
            hoverElevation: 4.0,
            highlightElevation: 8.0,
            onPressed: (String _) {},
          ),
        ),
      ),
    );
  }
}

Mouse cursor

The mouseCursor property defines the cursor shown while hovering over the action button.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: const <ChatMessage>[],
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            mouseCursor: SystemMouseCursors.click,
            onPressed: (String _) {},
          ),
        ),
      ),
    );
  }
}

Chat actionButton support

Shape

The shape property sets the button border shape.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: const <ChatMessage>[],
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            shape: const ContinuousRectangleBorder(
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(30.0),
                topRight: Radius.circular(15),
                bottomRight: Radius.circular(30.0),
                bottomLeft: Radius.circular(15),
              ),
            ),
            onPressed: (String _) {},
          ),
        ),
      ),
    );
  }
}

Chat actionButton support

Margin

The margin property defines external spacing around the action button. By default, it is EdgeInsetsDirectional.only(start: 8.0).

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: const <ChatMessage>[],
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            margin: const EdgeInsetsDirectional.only(start: 8.0),
            onPressed: (String _) {},
          ),
        ),
      ),
    );
  }
}

Size

The size property specifies button width and height. The default is Size.square(40.0).

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: const <ChatMessage>[],
          outgoingUser: '123-001',
          actionButton: ChatActionButton(
            size: const Size.square(40.0),
            onPressed: (String _) {},
          ),
        ),
      ),
    );
  }
}

Enable or disable action button

You can control action button interactivity in the following ways:

  • Set onPressed to null to disable the action button.
  • When using the default composer, set ChatComposer.decoration.enabled to false to disable both composer input and action button.
  • If composer is null, action button availability depends on your custom handling and onPressed.
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_chat/chat.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfChat(
          messages: const <ChatMessage>[],
          outgoingUser: '123-001',
          composer: const ChatComposer(
            decoration: InputDecoration(
              enabled: false,
              hintText: 'Composer disabled',
            ),
          ),
          actionButton: const ChatActionButton(onPressed: null),
        ),
      ),
    );
  }
}

You can refer to our Flutter Chat feature tour page for its groundbreaking feature representations. You can also explore our Flutter Chat example which demonstrates conversations between two or more users in a fully customizable layout and shows how to easily configure the chat with built-in support for creating stunning visual effects.

See Also