[SOLVED] Function callback to change text color (just for one) | Flutter

Issue

I’m trying to create a SideMenu with different SideMenuItems.
For that I created a new class and want to update the color of Text when the SideMenuItem is clicked. For that I want to transfer the activeState and all that stuff you see in the code below:

The use of my class in the Widget:

bool isActive = false;
...
            SideMenuItem(
              icon: Icon(
                Icons.inbox,
                size: 20,
                color: isActive ? kPrimaryColor : kGrayColor,
              ),
              activeState: isActive,
              title: "Archiv",
              toggleActiveState: (activeState) {
                setState(() {
                  isActive = !activeState;
                });
              },
            ),

And here is my class:

import 'package:flutter/material.dart';
import 'package:gastronomy/constants.dart';

class SideMenuItem extends StatelessWidget {
  // ignore: prefer_const_constructors_in_immutables
  SideMenuItem({
    Key? key,
    required this.activeState,
    this.itemCount = 0,
    this.showBorder = true,
    @required this.icon,
    @required this.title,
    required this.toggleActiveState,
  }) : super(key: key);

  final bool activeState;
  final bool showBorder;
  final int itemCount;
  final Icon? icon;
  final String? title;
  final Function(bool) toggleActiveState;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: kDefaultPadding),
      child: InkWell(
        onTap: () {
          toggleActiveState(activeState);
        },
        child: Row(
          children: [
            const SizedBox(width: 15),
            const SizedBox(width: kDefaultPadding / 4),
            Expanded(
              child: Container(
                padding: const EdgeInsets.only(bottom: 15, right: 5),
                decoration: showBorder
                    ? const BoxDecoration(
                        border: Border(
                          bottom: BorderSide(color: Color(0xFFDFE2EF)),
                        ),
                      )
                    : null,
                child: Row(
                  children: [
                    icon!,
                    const SizedBox(width: kDefaultPadding * 0.75),
                    Text(
                      title!,
                      style: Theme.of(context).textTheme.button?.copyWith(
                            color: activeState ? kTextColor : kGrayColor,
                          ),
                    ),
                    const Spacer(),
                    // if (itemCount != null) CounterBadge(count: itemCount)
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

I ended up with that pieces of code but well, how you might know, all SideMenuItems change there color when I click one.
I’m pretty new at using this way of code so I would be thankful to all informations you can include into your answer.

Solution

One option is to render all the menu items through a map function and compare each item with the selected option, like in the example below:

import 'package:flutter/material.dart';

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

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

class _MenuExampleState extends State<MenuExample> {
  List<String> menuOptions = const ['Item 1', 'Item 2', 'Item 3'];

  String selectedOption = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(
        backgroundColor: Colors.amber,
        child: ListView(
            children: menuOptions.map((menuOption) {
          return InkWell(
            onTap: () => setState(() {
              selectedOption = menuOption;
            }),
            child: MenuItem(
              name: menuOption,
              isSelected: menuOption == selectedOption,
            ),
          );
        }).toList()),
      ),
    );
  }
}

class MenuItem extends StatelessWidget {
  const MenuItem({Key? key, this.isSelected = false, required this.name})
      : super(key: key);

  final bool isSelected;
  final String name;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(
        name,
        style: TextStyle(
            fontWeight: isSelected ? FontWeight.bold : FontWeight.normal),
      ),
    );
  }
}

Answered By – Luiz Cardim

Answer Checked By – Marilyn (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.