Кнопки Flutter: ElevatedButton вместо RaisedButton, TextButton, FilledButton
Егор Долгов · 10.11.2026Во Flutter пять видов кнопок Material Design. Они различаются заметностью, а нажатие у всех задаётся одинаково — функцией в onPressed.
Кнопки Material Design во Flutter —
FilledButton
,
ElevatedButton
,
OutlinedButton
,
TextButton
и
IconButton
. Они различаются заметностью на экране, а действие по нажатию у всех задаётся одинаково — функцией в
onPressed
. Все примеры — в Material 3: эта версия дизайна во Flutter включена по умолчанию.
Если вы ищете
RaisedButton
или
FlatButton
:
их заменили —
RaisedButton
→
ElevatedButton
,
FlatButton
→
TextButton
,
OutlineButton
→
OutlinedButton
. Пример «было → стало», версии и замена
ButtonTheme
— в разделе 6.
Содержание:
- Какую кнопку выбрать
- Минимальный пример
- Основные параметры
- Примеры: неактивная кнопка, значок, размер
- Свой стиль: styleFrom и тема
- Чем заменить RaisedButton, FlatButton, OutlineButton и ButtonTheme
- Частые ошибки
1. Какую кнопку выбрать
По документации Flutter:
-
FilledButton— самая заметная из этих кнопок, для главного действия, которое завершает шаг: «Сохранить», «Подтвердить». Заметнее неё толькоFloatingActionButton— круглая плавающая кнопка в углу экрана. -
FilledButton.tonal— промежуточный вариант междуFilledButtonиOutlinedButton: залит дополнительным, более спокойным цветом темы — заметнее кнопки с рамкой, но тише залитой. Например, «Далее». -
ElevatedButton— приподнятая кнопка с тенью. Нужна, чтобы добавить объём плоскому макету, например в длинном списке. Не ставьте её на приподнятые элементы: диалоги и карточки. -
OutlinedButton— кнопка с рамкой: для важного, но не главного действия. -
TextButton— кнопка без рамки: на панелях, в диалогах, рядом с текстом. Не ставьте её туда, где она сольётся с содержимым, например посреди списка. -
IconButton— кнопка-значок, часто в шапке приложения (AppBar.actions).
2. Минимальный пример
Пять видов кнопок и вариант
FilledButton.tonal
на одном экране:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Кнопки')),
body: const Center(child: ButtonsDemo()),
),
);
}
}
class ButtonsDemo extends StatelessWidget {
const ButtonsDemo({super.key});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
spacing: 12,
children: [
FilledButton(onPressed: () {}, child: const Text('FilledButton')),
FilledButton.tonal(
onPressed: () {},
child: const Text('FilledButton.tonal'),
),
ElevatedButton(onPressed: () {}, child: const Text('ElevatedButton')),
OutlinedButton(onPressed: () {}, child: const Text('OutlinedButton')),
TextButton(onPressed: () {}, child: const Text('TextButton')),
IconButton(onPressed: () {}, icon: const Icon(Icons.favorite_border)),
],
);
}
}
На экране — столбец из шести кнопок по центру, между ними по 12 пикселей (
spacing: 12
).
3. Основные параметры
Общие параметры
FilledButton
,
ElevatedButton
,
OutlinedButton
и
TextButton
:
-
onPressed(VoidCallback?) — функция, которую кнопка вызовет при нажатии. -
onLongPress(VoidCallback?) — функция для долгого нажатия. -
child(Widget?) — что на кнопке, обычноText. Передавать обязательно. -
style(ButtonStyle?) — вид кнопки: цвета, отступы, размер, форма (раздел 5).
VoidCallback
— функция без параметров, которая ничего не возвращает, например
() { … }
. Знак
?
после типа значит, что вместо значения можно передать
null
. У
IconButton
вместо
child
— обязательный
icon
.
4. Примеры: неактивная кнопка, значок, размер
Как сделать кнопку неактивной, добавить значок и долгое нажатие
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(body: Center(child: Variants())),
),
);
}
class Variants extends StatelessWidget {
const Variants({super.key});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
spacing: 12,
children: [
// Неактивная кнопка: onPressed и onLongPress равны null.
const ElevatedButton(onPressed: null, child: Text('Недоступна')),
// Кнопка со значком.
FilledButton.icon(
onPressed: () {},
icon: const Icon(Icons.send),
label: const Text('Отправить'),
),
// Долгое нажатие.
TextButton(
onPressed: () {},
onLongPress: () {},
child: const Text('Нажмите и держите'),
),
// Варианты IconButton.
Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(onPressed: () {}, icon: const Icon(Icons.add)),
IconButton.filled(onPressed: () {}, icon: const Icon(Icons.add)),
IconButton.filledTonal(
onPressed: () {},
icon: const Icon(Icons.add),
),
IconButton.outlined(onPressed: () {}, icon: const Icon(Icons.add)),
],
),
],
);
}
}
На экране — столбец: бледная неактивная кнопка, кнопка со значком, текстовая кнопка и ряд из четырёх кнопок-значков.
-
Неактивная кнопка.
Если
onPressedиonLongPressравныnull, кнопка выключена: не реагирует на нажатия, и Flutter рисует её приглушёнными цветами неактивного состояния.IconButtonвыключается однимonPressed: null. -
Кнопка со значком.
У
FilledButton,ElevatedButton,OutlinedButtonиTextButtonесть конструктор.icon: значок — вicon, текст — в обязательномlabel. ДляFilledButton.tonal—FilledButton.tonalIcon. -
Долгое нажатие.
onLongPressвызывается, когда кнопку нажали и держат. -
Варианты
IconButton. Кроме обычного, естьIconButton.filled,IconButton.filledTonalиIconButton.outlined— с заливкой основным цветом, с заливкой спокойным цветом и с рамкой.
Как задать размер кнопки и сделать её на всю ширину
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(body: Center(child: Sizes())),
),
);
}
class Sizes extends StatelessWidget {
const Sizes({super.key});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
spacing: 12,
children: [
// Точный размер: 200 × 60.
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(fixedSize: const Size(200, 60)),
child: const Text('200 × 60'),
),
// На всю ширину: SizedBox с бесконечной шириной.
SizedBox(
width: double.infinity,
child: FilledButton(
onPressed: () {},
child: const Text('На всю ширину'),
),
),
],
);
}
}
На экране — кнопка 200 × 60 и под ней кнопка на всю ширину экрана.
-
fixedSizeвstyleFromзадаёт размер кнопки: здесь 200 × 60. Только ширину —Size.fromWidth(320), только высоту —Size.fromHeight(100). -
Кнопка на всю ширину — внутри
SizedBox(width: double.infinity):SizedBoxс бесконечной шириной растягивает кнопку на всю ширину, которую даёт родитель. -
minimumSizeзадаёт наименьший размер: по умолчанию уElevatedButtonв Material 3 — 64 × 40.
Раньше размер задавали через
ButtonTheme(minWidth:, height:)
; у новых кнопок для этого
fixedSize
и
minimumSize
.
5. Свой стиль: styleFrom и тема
Вид кнопки задаёт объект
ButtonStyle
в параметре
style
. Проще всего собрать его методом
styleFrom
— из цветов, отступов и размеров. Этот метод есть у каждой кнопки:
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(body: Center(child: StyledButton())),
),
);
}
class StyledButton extends StatelessWidget {
const StyledButton({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.deepPurple,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
child: const Text('Своя кнопка'),
);
}
}
На экране — фиолетовая кнопка с белым текстом и углами, скруглёнными на 8. По умолчанию края у неё полукруглые — это и меняет
shape
.
-
backgroundColor— цвет фона,foregroundColor— цвет текста и значка. -
padding— внутренние отступы,shape— форма: здесь прямоугольник со скруглением 8. -
У выключенной кнопки
backgroundColorиforegroundColorне действуют — для неё естьdisabledBackgroundColorиdisabledForegroundColor(пример в разделе 6).
Другие параметры
styleFrom
—
minimumSize
,
fixedSize
,
elevation
,
side
(рамка),
textStyle
— описаны в
справке ElevatedButton.styleFrom
.
Чтобы не повторять
style
у каждой кнопки, задайте его в теме приложения — объекте
ThemeData
в параметре
theme
у
MaterialApp
. У каждого вида кнопок своё поле в
ThemeData
:
elevatedButtonTheme
,
filledButtonTheme
,
outlinedButtonTheme
,
textButtonTheme
,
iconButtonTheme
. В поле передаётся объект
…ThemeData
, например
ElevatedButtonThemeData
:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(minimumSize: const Size(200, 48)),
),
),
home: Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {},
child: const Text('Размер из темы'),
),
),
),
),
);
}
Теперь у всех
ElevatedButton
в приложении минимальный размер — 200 × 48.
6. Чем заменить RaisedButton, FlatButton, OutlineButton и ButtonTheme
Замены — из руководства по миграции :
-
RaisedButton→ElevatedButton; тема:elevatedButtonTheme: ElevatedButtonThemeData(…) -
FlatButton→TextButton; тема:textButtonTheme: TextButtonThemeData(…) -
OutlineButton→OutlinedButton; тема:outlinedButtonTheme: OutlinedButtonThemeData(…)
Параметры цвета старых кнопок (
color
,
textColor
) переехали в
styleFrom
:
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(body: Center(child: SaveButton(enabled: true))),
),
);
}
class SaveButton extends StatelessWidget {
const SaveButton({super.key, required this.enabled});
final bool enabled;
@override
Widget build(BuildContext context) {
// Было: RaisedButton(color: Colors.blue, textColor: Colors.white, …)
return ElevatedButton(
onPressed: enabled ? () {} : null,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
disabledBackgroundColor: Colors.blueGrey,
disabledForegroundColor: Colors.white70,
),
child: const Text('Сохранить'),
);
}
}
Старые кнопки объявили устаревшими во Flutter 2.0.
OutlineButton
удалили к версии 3.0,
RaisedButton
и
FlatButton
— к 3.3. Поэтому код из старых статей на современном Flutter не собирается.
ButtonTheme
для новых кнопок не используется: вид задаёт один объект
ButtonStyle
вместо множества отдельных параметров — через
style
и
styleFrom
(раздел 5), а для всех кнопок сразу — через тему.
7. Частые ошибки
-
The method 'RaisedButton' isn't defined for the type '…'. Если в кодеnew RaisedButton(…), текст другой —The name 'RaisedButton' isn't a class, а если кнопка создаётся вне класса —The function 'RaisedButton' isn't defined. Код написан для старой версии Flutter — замените кнопку по таблице раздела 6. Так же выглядят ошибки сFlatButtonиOutlineButton. -
Кнопка бледная и не нажимается.
У неё
onPressed(иonLongPress) равныnull— например, передали переменную, которая ещёnull. Такая кнопка выключена. -
Цвет из
styleFromне применяется. Проверьте, что кнопка не выключена: у неёonPressedнеnull. Цвет выключенной кнопки задаютdisabledBackgroundColorиdisabledForegroundColor. -
onPressed: _save()со скобками. Так кнопке передаётся не функция, а результат её вызова. Если функция ничего не возвращает (void), анализатор выдаст ошибкуuse_of_void_result. НужноonPressed: _save— без скобок — илиonPressed: () { … }.
Смотрите также:
Урок 1
— первая кнопка
FilledButton
в приложении; справка
ButtonStyle
,
FilledButton
,
IconButton
.
Вопросы и предложения по статье присылайте на contact@flutter.su.