Having a row of buttons for selecting moods in flutter

48 Views Asked by At

I want to make a row of buttons sort of like the ones in this picture

sort of like this

except i want the icons to be numbers and the selected button to be a different color to the rest of the items

I can't really find anything that has what I need as i also need to have one of the selectors to only show up when a true or false button above has also been selected. and I also need to return whether or not the true or false has been selected.

if anyone has any ideas or advice on how I would go about doing this, I would seriously just appreciate it so so much. thank you so much in advance

2

There are 2 best solutions below

0
WebDesk Solution On BEST ANSWER

Please review the code below, which I hope will be helpful to you.

int _selectedIndex = -1; // Initially no button is selected


 Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: List.generate(5, (index) {
                return IconButton(
                  icon: _buildIcon(index),
                  onPressed: () {
                    setState(() {
                      _selectedIndex = index;
                    });
                  },
                  color: _selectedIndex == index ? Colors.green : null,
                );
              }),
            ),

Define different icons based on rating level

  Icon _buildIcon(int index) {
    switch (index) {
      case 0:
        return Icon(Icons.sentiment_very_dissatisfied); // Lowest rating
      case 1:
        return Icon(Icons.sentiment_dissatisfied); // Moderate-low rating
      case 2:
        return Icon(Icons.sentiment_neutral); // Neutral rating
      case 3:
        return Icon(Icons.sentiment_satisfied); // Moderate-high rating
      case 4:
        return Icon(Icons.sentiment_very_satisfied); // Highest rating
      default:
        return Icon(Icons.star_border); // Default icon
    }
  }

Output:

enter image description here

0
RaYmMiE On

First advice i can give to you is to do things step by step.

You will need a Row who contains your items.

Each item can be a Container with a Text widget inside.

You can use InkWell on top of each container to "detect" user input.

You will need to use states to handle changes (like when user tap on the number).

There is multiples ways to use states but i see one who can be easy to setup :

Each container use int value conditional (for color for example) like :

color: selected == 1 ? Colors.redAccent : Colors.transparent

After you need to add a setState function in your InkWell onTap who will set the int selected variable to the value you want.

I made the full example :

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(
      title: 'MyApp',
      home: Scaffold(
        body: HappySelector(),
      ),
    );
  }
}

class HappySelector extends StatefulWidget {
  const HappySelector({super.key});

  @override
  State<HappySelector> createState() => _HappySelectorState();
}

class _HappySelectorState extends State<HappySelector> {
  int selected = 0;

  @override
  Widget build(BuildContext context) {
    return Center(child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
          InkWell(
            onTap: () {
             setState(() {
                  selected = 1;
                });
            },
            child:
               Container(
                 color: selected == 1 ? Colors.red : Colors.transparent,
                 child: 
                   Text("1")
               )
          ),
          InkWell(
            onTap: () {
             setState(() {
                  selected = 2;
                });
            },
            child:
               Container(
                 color: selected == 2 ? Colors.green : Colors.transparent,
                 child: 
                   Text("2")
               )
          ),
        ]));
  }
}