betacode

Руководство Flutter TextButton

  1. TextButton
  2. Examples
  3. child
  4. onPressed
  5. onLongPress
  6. style
  7. autofocus
  8. focusNode
  9. clipBehavior

1. TextButton

В Flutter,TextButton используется для создания кнопки, содержащей текст с идеей создания плоской кнопки (flat button) с высотой (elevation) 0 по умолчанию. Но на самом деле вы можете изменить её стиль с помощью свойства style.
Примечание: Раньше для создания плоской кнопки мы использовали класс FlatButton. Однако с октября 2020 года этот класс был помечен как устаревший, и он был заменен классом TextButton. Это одна из попыток команды разработчиков Flutter, которые направленны на упрощение и согласование Flutter API.
TextButton Constructor:
TextButton Constructor
const TextButton({Key key,
   @required Widget child,
   @required VoidCallback onPressed,
   VoidCallback onLongPress,
   ButtonStyle style,
   FocusNode focusNode,
   bool autofocus: false,
   Clip clipBehavior: Clip.none
 }
)
Можно использовать TextButton в панелях инструментов, диалоговых окнах (Dialog) и т. д. Но иногда вам нужно изменить её стиль (style), чтобы избежать путаницы у пользователей. Или когда вы используете её как плоскую кнопку (flat button), вы должны поместить её на месте, соответствующем контексту. Нельзя помещатьTextButton на месте, где она смешивается с другим содержимым, например, в середине списка.
TextButton.icon Constructor:
TextButton.icon Constructor
TextButton.icon(
    {Key key,
    @required Widget icon,
    @required Widget label,
    @required VoidCallback onPressed,
    VoidCallback onLongPress,
    ButtonStyle style,
    FocusNode focusNode,
    bool autofocus,
    Clip clipBehavior}
)
Если обе функции callback:onPressed и onLongPress, не указаны, TextButton будет отключена (disabled) и не будет иметь ответа при касании.

2. Examples

Ниже приведен пример, включающий две TextButton. Одна из них - самая простая TextButton (содержащая только одну текстовую метку), а другая - TextButton с цветом фона (backgroundColor) и цветом текста (foregroundColor).
main.dart (ex1)
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'o7planning',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(

        appBar: AppBar(
          title: Text("Flutter TextButton Example")
        ),
        body: Center (
            child: Column (
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                TextButton (
                  child: Text("Default TextButton"),
                  onPressed: () {},
                ),
                TextButton (
                    child: Text("TextButton With Background and Foreground Color"),
                    onPressed: () {},
                    style: ButtonStyle(
                      backgroundColor: MaterialStateProperty.all<Color>(Colors.greenAccent),
                      foregroundColor: MaterialStateProperty.all<Color>(Colors.red),
                    )
                )
              ],
            )
        )
    );
  }
}
Самый удобный способ сделать TextButton, содержащую значок - это использовать конструктор TextButton.icon.
TextButton.icon (
  icon: Icon(Icons.settings),
  label: Text("Settings"),
  onPressed: () {},
)

3. child

child - это самое важное свойство TextButton. В большинстве случаев это свойство используется в качестве объекта Text.
@required Widget child
Самый простой пример с child - это объект Text:
TextButton (
  child: Text("Default TextButton"),
  onPressed: () {},
)
Путём присвоения объекта Row свойству child, можно создать более сложную TextButton, включающую как Icon, так и Text.
child (ex1)
// 1 Icon and 1 Text
TextButton (
  child: Row (
    children: [
      Icon(Icons.settings),
      SizedBox(width: 5),
      Text("Settings")
    ],
  ) ,
  onPressed: () {},
)

// 2 Icons and 1 Text
TextButton (
  child: Row (
    children: [
      Icon(Icons.directions_bus),
      Icon(Icons.train),
      SizedBox(width: 5),
      Text("Transportation")
    ],
  ) ,
  onPressed: () {},
)

4. onPressed

onPressed - это функция обратного callback. Она вызывается, когда пользователь нажимает (click) Button. В частности, событие onPressed произойдет, когда пользователь завершит два действия, включающих нажатие (press down) и отпускание (release) кнопки.
@required VoidCallback onPressed
Примечание: Если свойства onPressed и onLongPress не указаны, кнопка будет отключена и не будет реагировать на касания.
main.dart (onPressed - ex1)
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'o7planning.org',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return MyHomePageState();
  }
}

class MyHomePageState extends State<MyHomePage> {
  int pressCount = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold (
        appBar: AppBar(
          title: Text("Flutter TextButton Example"),
        ),
        body: Center (
          child:  TextButton (
              child: Text("Click Me! " + this.pressCount.toString()),
              onPressed: onPressHander
          ),
        )
    );
  }

  onPressHander()  {
    this.setState(() {
      this.pressCount++;
    });
  }

}

5. onLongPress

onLongPress - это функция callback. Она вызывается, когда пользователь нажимает (press down) кнопку в течение времени более LONG_PRESS_TIMEOUT миллисекунд. Событие Long-Press будет происходить в LONG_PRESS_TIMEOUT-момент времени после нажатия пользователем, если в течение этого времени (0 -> LONG_PRESS_TIMEOUT) курсор мыши не перемещается.
VoidCallback onLongPress
Если вы назначите две функции callback: onPressed и onLongPress для одной кнопки, то в любой ситуации будет вызвана не более одной функции.
LONG_PRESS_TIMEOUT
500 milliseconds
Если пользователь нажмет (press down) и отпустит (release) её до времени LONG_PRESS_TIMEOUT, произойдет только одно событие onPressed.
Если пользователь нажмет её дольше, чем LONG_PRESS_TIMEOUT миллисекунд, произойдет событие onLongPress, и Flutter проигнорирует событие onPressed, которое произойдет после этого.
Например:
main.dart (onLongPress - ex1)
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'o7planning.org',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return MyHomePageState();
  }
}

class MyHomePageState extends State<MyHomePage> {
  int pressedCount = 0;
  int longPressCount = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold (
        appBar: AppBar(
          title: Text("Pressed: " + this.pressedCount.toString()
              +" --- Long Press: " + this.longPressCount.toString()),
        ),
        body: Center (
          child:  TextButton (
              child: Text("Test Me"),
              onPressed: onPressHander,
              onLongPress: onLongPressHandler
          ),
        )
    );
  }

  onPressHander()  {
    this.setState(() {
      this.pressedCount++;
    });
  }

  onLongPressHandler()  {
    this.setState(() {
      this.longPressCount++;
    });
  }

}

6. style

Свойство style используется для настройки стиля TextButton.
ButtonStyle style
ButtonStyle constructor
const ButtonStyle(
    {MaterialStateProperty<TextStyle> textStyle,
    MaterialStateProperty<Color> backgroundColor,
    MaterialStateProperty<Color> foregroundColor,
    MaterialStateProperty<Color> overlayColor,
    MaterialStateProperty<Color> shadowColor,
    MaterialStateProperty<double> elevation,
    MaterialStateProperty<EdgeInsetsGeometry> padding,
    MaterialStateProperty<Size> minimumSize,
    MaterialStateProperty<BorderSide> side,
    MaterialStateProperty<OutlinedBorder> shape,
    MaterialStateProperty<MouseCursor> mouseCursor,
    VisualDensity visualDensity,
    MaterialTapTargetSize tapTargetSize,
    Duration animationDuration,
    bool enableFeedback}
)
Например, TextButton с изменяемым цветом фона (background color) и цветом текста (foreground color) в зависимости от её состояния.
TextButton (
    child: Text("TextButton 1"),
    onPressed: () {},
    style: ButtonStyle (
        backgroundColor: MaterialStateProperty.resolveWith<Color>(
                (Set<MaterialState> states) {
              if (states.contains(MaterialState.pressed)) {
                return Colors.red;
              }
              return null; // Use the component's default.
            }
        ),
        foregroundColor: MaterialStateProperty.resolveWith<Color>(
              (Set<MaterialState> states) {
            if (states.contains(MaterialState.pressed)) {
              return Colors.yellow;
            }
            return null; // Use the component's default.
          },
        )
    )
)
Например: TextButton с высотой (elevation) 10, в нажатом состоянии (pressed) будет иметь высоту 0.
TextButton (
    child: Text("TextButton 2"),
    onPressed: () {},
    style: ButtonStyle(
      backgroundColor: MaterialStateProperty.resolveWith<Color>(
              (Set<MaterialState> states) {
            if (states.contains(MaterialState.disabled)) {
              return Colors.black26;
            }
            return Colors.cyan;
          }
      ),
      foregroundColor: MaterialStateProperty.all<Color>(Colors.red),
      elevation: MaterialStateProperty.resolveWith<double>(
            (Set<MaterialState> states) {
          if (states.contains(MaterialState.pressed)
               ||  states.contains(MaterialState.disabled)) {
            return 0;
          }
          return 10;
        },
      )
    )
)
  • ButtonStyle
  • MaterialStateProperty

7. autofocus

bool autofocus: false
  • Flutter change Focus

8. focusNode

FocusNode focusNode
  • Руководство Flutter FocusNode

9. clipBehavior

Clip clipBehavior: Clip.none
  • Flutter Clip clipBehavior

Pуководства Flutter

Show More