DanMossa
DanMossa

Reputation: 1082

How to make ToggleButtons with text under icon

I'm having a bit of a hard time with this idea.

The goal is to have a row of Toggle Icons with text that can overflow onto a second line.

The issue I'm having with the ToggleButtons is that I can't seem to place text underneath each icon.

I currently have a Map<String, Icon> where the string is the text I want below the Icon from that Map.

Is there an easy/possible way to do this?

Upvotes: 2

Views: 2364

Answers (4)

CNK
CNK

Reputation: 703

You can also create a custom widget and use it when you need it.

///CustomTextIcon.dart

import 'package:flutter/material.dart';

class MyIconWithText extends StatelessWidget {
  final IconData icon;
  final String? text;

  const MyIconWithText(this.icon, {Key? key,
    this.text
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Icon(icon),
        const SizedBox(height: 5.0,),
        Text(text ?? ""),
      ],
    );
  }
}

and use it as follow:

///Used as a widget
MyIconWithText(Icons.disabled_by_default, text: "Description")

Upvotes: 0

DanMossa
DanMossa

Reputation: 1082

I edited up modifying another answers code from another question to use my map

import 'package:flutter/material.dart';

class WrapToggleIconButtons extends StatefulWidget {
  const WrapToggleIconButtons({
    @required this.symptomIconDataMap,
    @required this.isSelected,
    @required this.onPressed,
  });

  final Map<String, IconData> symptomIconDataMap;
  final List<bool> isSelected;
  final Function onPressed;

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

class _WrapToggleIconButtonsState extends State<WrapToggleIconButtons> {
  int index;

  @override
  Widget build(BuildContext context) {
    final List<String> symptomsList = widget.symptomIconDataMap.keys.toList();
    assert(symptomsList.length == widget.isSelected.length);
    index = -1;
    return Wrap(
      children: symptomsList.map((String symptom) {
        index++;
        return IconToggleButton(
          active: widget.isSelected[index],
          iconData: widget.symptomIconDataMap[symptom],
          text: symptom,
          onTap: widget.onPressed,
          index: index,
        );
      }).toList(),
    );
  }
}

class IconToggleButton extends StatelessWidget {
  const IconToggleButton({
    @required this.active,
    @required this.iconData,
    @required this.text,
    @required this.onTap,
    @required this.index,
    this.width,
    this.height,
  });

  final bool active;
  final IconData iconData;
  final String text;
  final Function onTap;
  final double width;
  final double height;
  final int index;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 80.0,
      height: height ?? 60.0,
      child: Column(
        children: [
          InkWell(
            child: Icon(
              iconData,
              color: active ? Theme.of(context).accentColor : Theme.of(context).disabledColor,
            ),
            onTap: () => onTap(index),
          ),
          Wrap(
            direction: Axis.horizontal,
            children: [
              Text(
                text,
                textAlign: TextAlign.center,
              ),
            ],
          )
        ],
      ),
    );
  }
}

Flutter: Is there a widget to flex toggle buttons

Upvotes: 0

bluenile
bluenile

Reputation: 6029

Please see the following code to put text under icon in a ToggleButton.

import 'package:flutter/material.dart';

final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  Map<String, dynamic> map = {
    "one": Icons.ac_unit,
    "two": Icons.baby_changing_station,
    "three": Icons.cached,
    "four": Icons.dangerous,
    "five": Icons.east,
    "six": Icons.face,
  };
  List<bool> _isSelected = [];

  @override
  void initState() {
    super.initState();
    _isSelected = List.filled(map.length, false);
  }

  @override
  Widget build(BuildContext context) {
    return Wrap(
      children: [
        ToggleButtons(
          isSelected: _isSelected,
          children: [
            ...map.entries.map((ele) {
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Icon(ele.value),
                  Text(ele.key),
                ],
              );
            }).toList(),
          ],
          selectedColor: Colors.blueGrey,
          onPressed: (value) {
            setState(() {
              _isSelected = List.filled(map.length, false);
              _isSelected[value] = true;
            });
          },
        ),
      ],
    );
  }
}

Upvotes: 0

Tomas
Tomas

Reputation: 1051

Yea, you can achieve this by using the Column widget.

return Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Icon(Icons.access_alarm),
    SizedBox(height: 5.0,),
    Text("Text"),
  ],
);

Upvotes: 2

Related Questions