Leena Marie
Leena Marie

Reputation: 347

Adding a trailing icon to a TextButton?

Is there a way to add a trailing icon to a TextButton?

Here's my code:

TextButton(
       child: Center(
         child: Text ('Dummy', style: GoogleFonts.openSans (
             color: Colors.white, fontWeight: FontWeight.w400,
             fontSize: 28),),
       ),
       onPressed: () {
         Navigator.push(
           context,
           MaterialPageRoute(builder: (context) => FourteenthRoute(),),);
       }
   ),

Upvotes: 2

Views: 3762

Answers (5)

Gowsik Raja
Gowsik Raja

Reputation: 732

You can simply swap label and icon like below.

TextButton.icon(
              onPressed: () {},
              label: const Icon(Icons.expand_more),
              icon: const Text('View documents'))

Upvotes: 0

Sparsh Jain
Sparsh Jain

Reputation: 823

You can simply child widget of the TextButton with Row widget.

          TextButton(
            onPressed: () => {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => FourteenthRoute(),
                ),
              )
            },
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(
                  "Dummy",
                  style: GoogleFonts.openSans(
                      color: Colors.white,
                      fontWeight: FontWeight.w400,
                      fontSize: 28),
                ),
                Icon(Icons.menu)
              ],
            ),
          ),

Upvotes: 2

ישו אוהב אותך
ישו אוהב אותך

Reputation: 29783

TextButton doesn't support trailing icon yet. But you can create your custom TextButton by slightly modifying the source code. See https://github.com/flutter/flutter/blob/18116933e7/packages/flutter/lib/src/material/text_button.dart#L153

Here a custom TextButton with trailing icon (custom_text_button.dart):

import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'dart:ui' show lerpDouble;

class CustomTextButton extends TextButton {
  factory CustomTextButton.icon({
    Key? key,
    required VoidCallback? onPressed,
    VoidCallback? onLongPress,
    ButtonStyle? style,
    FocusNode? focusNode,
    bool? autofocus,
    Clip? clipBehavior,
    required Widget icon,
    required Widget label,
    Widget? trailing,
  }) = CustomTextButton;

  CustomTextButton({
    Key? key,
    required VoidCallback? onPressed,
    VoidCallback? onLongPress,
    ButtonStyle? style,
    FocusNode? focusNode,
    bool? autofocus,
    Clip? clipBehavior,
    required Widget icon,
    required Widget label,
    Widget? trailing,
  })  : assert(icon != null),
        assert(label != null),
        super(
        key: key,
        onPressed: onPressed,
        onLongPress: onLongPress,
        style: style,
        focusNode: focusNode,
        autofocus: autofocus ?? false,
        clipBehavior: clipBehavior ?? Clip.none,
        child: _TextButtonWithIconChild(icon: icon, label: label, trailing:trailing),
      );

  @override
  ButtonStyle defaultStyleOf(BuildContext context) {
    final EdgeInsetsGeometry scaledPadding = ButtonStyleButton.scaledPadding(
      const EdgeInsets.all(8),
      const EdgeInsets.symmetric(horizontal: 4),
      const EdgeInsets.symmetric(horizontal: 4),
      MediaQuery.maybeOf(context)?.textScaleFactor ?? 1,
    );
    return super.defaultStyleOf(context).copyWith(
      padding: MaterialStateProperty.all<EdgeInsetsGeometry>(scaledPadding),
    );
  }
}

class _TextButtonWithIconChild extends StatelessWidget {
  const _TextButtonWithIconChild({
    Key? key,
    required this.label,
    required this.icon,
    this.trailing,
  }) : super(key: key);

  final Widget label;
  final Widget icon;
  final Widget? trailing;

  @override
  Widget build(BuildContext context) {
    final double scale = MediaQuery.maybeOf(context)?.textScaleFactor ?? 1;
    final double gap =
    scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!;
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        icon,
        SizedBox(width: gap),
        Flexible(child: label),
        if (trailing != null) SizedBox(width: gap),
        if (trailing != null) trailing!,
      ],
    );
  }
}

sample main:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

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

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

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CustomTextButton.icon(
              icon: Icon(Icons.camera),
              label: Text('Take A Photo'),
              trailing: Icon(Icons.edit),
              onPressed: () {},
            )
          ],
        ),
      ),
    );
  }
}

result:

CustomTextButton.icon

Upvotes: 0

yassine
yassine

Reputation: 88

Try out this package : https://pub.dev/packages/styled_text

  TextButton(
           child: Center(
             child: StyledText(
                text: 'Text with alarm <alarm/> icon.',
                tags: {
                       'alarm': StyledTextTagIcon(Icons.alarm),
               },
              ),
           ),
           onPressed: () {
             Navigator.push(
               context,
               MaterialPageRoute(builder: (context) => FourteenthRoute(),),);
           }
       ),

result

Upvotes: 0

iStornZ
iStornZ

Reputation: 858

you can use TextButton.icon() :)

Upvotes: 2

Related Questions