How change the Icon of an IconButton when it is pressed
Asked Answered
M

5

6

I want to know how I can change the Icon of an IconButton when it is pressed. (Favorite_border to Favorite). I tried somethings but it doesn't works. Maybe it is easy but I am a beginner and I don't understand very well how it is works.

Update

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../recyclerview/data.dart';
import 'package:watch/constants.dart';

int itemCount = item.length;
List<bool> selected = new List<bool>();

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  initState() {
    for (var i = 0; i < itemCount; i++) {
    selected.add(false);
    }
    super.initState();
  }
 
  Icon notFavorite = Icon(Icons.favorite_border, size: 25,);
  Icon inFavorite = Icon(Icons.favorite, size: 25,);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
         title: Text('Accueil', style: kAppBarStyle,),
          //backgroundColor: Colors.white,  
          elevation: 0,
      ),
      body:  ListView.builder(
        itemCount: itemCount,
        itemBuilder: (BuildContext context, int index) {
      return Container(
        child: new Row(
          children: <Widget>[
            //Image
            new Container(
              margin: new EdgeInsets.all(5.0),
              child: new CachedNetworkImage(
                imageUrl: item[index].imageURL,
                height: MediaQuery.of(context).size.width / 4,
                width: MediaQuery.of(context).size.width / 2,
                fit: BoxFit.cover,
              ),
            ),
            //Text
            Expanded(
              child: new Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Spacer(),               
                //Titre
                Container(
                  padding: const EdgeInsets.only(bottom: 75.0, top: 10.0 ),
                  child: Text(
                    item[index].title,
                    style: kItemTitle,
                  ),
                ),
                //Decription
                Container(
                  padding: const EdgeInsets.only(left: 10.0, top: 10.0),
                  child:Text(
                    item[index].description,
                    style: kItemDescription,
                  ),
                ),
                //Favoris
                Spacer(),
                GestureDetector(
                  child: Container(
                    padding: const EdgeInsets.only(right: 10.0, top: 3.0),
                    child: selected.elementAt(index) ? inFavorite : notFavorite,
                  ),
                  onTap: () {
                    setState(() {
                      selected[index] = !selected.elementAt(index);
                    });
                    },
                ),
              ],
            ),
          ),
        ],
      ),
    );
    }
    )
  );
}
}

It is a ListView with Images, Texts and the Favorite Button and it works fine.

Metallize answered 18/10, 2020 at 20:13 Comment(4)
probably duplicate #50185857Ambulator
Please show us what you have tried in a minimal example. Otherwise we can not help you.Tillfourd
I have posted my codeMetallize
Does this answer your question? how to change icon color immediately after pressed in flutter?Grisette
N
3

custom radio button (some IconButton in ListView that change their icons):

main.dart file :

import 'package:flutter/material.dart';
import 'my_home_page.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

my_home_page.dart file:

import 'package:flutter/material.dart';

int itemCount = 5;
List<bool> selected = new List<bool>();

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

   @override
   initState() {
     for (var i = 0; i < itemCount; i++) {
        selected.add(false);
     }
     super.initState();
   }

  Icon firstIcon = Icon(
    Icons.radio_button_on, // Icons.favorite
    color: Colors.blueAccent, // Colors.red
    size: 35,
  );
  Icon secondIcon = Icon(
    Icons.radio_button_unchecked, // Icons.favorite_border
    color: Colors.grey,
    size: 35,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: ListView.builder(
            itemCount: itemCount,
            itemBuilder: (BuildContext context, int index) {
              return IconButton(
                icon: selected.elementAt(index) ? firstIcon : secondIcon,
                onPressed: () {
                  try {
                    // your code that you want this IconButton do
                    setState(() {
                      selected[index] = !selected.elementAt(index);
                    });
                    print('tap on ${index + 1}th IconButton ( change to : ');
                    print(selected[index] ? 'active' : 'deactive' + ' )');
                  } catch (e) {
                    print(e);
                  }
                },
              );
            }),
      ),
    );
  }
}
Naevus answered 19/10, 2020 at 14:9 Comment(4)
Thanks it works but when I change of pages and return on my home page, the Button which were selected are not. How I can save the button which are selected ?Metallize
you should define your List<bool> in global for accessibility everywhere. for example, you can move this to out of the classes and ext.Naevus
move your List<bool> out of calss in global and set initial value in initState with this lines in class : @override initState() { for (var i = 0; i < itemCount; i++) { selected.add(false); } super.initState(); }Naevus
I'm not sure to understand can you give me the example pleaseMetallize
P
12

First you need a boolean variable.

  bool toggle = false;

After that you can use IconButton like this:

   IconButton(
          icon: toggle
              ? Icon(Icons.favorite_border)
              : Icon(
                  Icons.favorite,
                ),
          onPressed: () {
            setState(() {
              // Here we changing the icon.
              toggle = !toggle;
            });
          }),
Portis answered 18/10, 2020 at 20:22 Comment(1)
It works but I have this Icon button in a ListView and when I click, it changes all the IconButtons ? How I can do for just change the Icon which is pressed.Metallize
G
3

Copy paste the code and it will work :)

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: HomeApp(),
    );
  }
}

class HomeApp extends StatefulWidget {
  @override
  _HomeAppState createState() => _HomeAppState();
}

class _HomeAppState extends State<HomeApp> {
  // Using a Bool
  bool addFavorite = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter App :)"),
      ),
      body: Center(
        child: IconButton(
            icon: Icon(addFavorite ? Icons.favorite : Icons.favorite_border),
            onPressed: () {
              // Setting the state
              setState(() {
                addFavorite = !addFavorite;
              });
            }),
      ),
    );
  }
}

Updating the Code for ListView

class _HomeAppState extends State<HomeApp> {
  // Using a Bool List for list view builder
  List<bool> addFavorite = List<bool>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter App :)"),
      ),
      body: ListView.builder(
          itemCount: 10,
          itemBuilder: (context, index) {
            // Setting a bool initially
            addFavorite.add(false);
            return IconButton(
                icon: Icon(addFavorite.elementAt(index)
                    ? Icons.favorite
                    : Icons.favorite_border),
                onPressed: () {
                  // Setting the state
                  setState(() {
                    // Changing icon of specific index
                    addFavorite[index] =
                        addFavorite[index] == false ? true : false;
                  });
                });
          }),
    );
  }
}
Guienne answered 18/10, 2020 at 20:25 Comment(3)
It works but I have this Icon button in a ListView and when I click, it changes all the IconButtons ? How I can do for just change the Icon which is pressed.Metallize
Added the ListView.builder portion. You can copy paste the code it will work fine. Don't forget to mark the answer plz :)Guienne
How to we make the star bulge out when you press it?Aeschines
N
3

custom radio button (some IconButton in ListView that change their icons):

main.dart file :

import 'package:flutter/material.dart';
import 'my_home_page.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

my_home_page.dart file:

import 'package:flutter/material.dart';

int itemCount = 5;
List<bool> selected = new List<bool>();

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

   @override
   initState() {
     for (var i = 0; i < itemCount; i++) {
        selected.add(false);
     }
     super.initState();
   }

  Icon firstIcon = Icon(
    Icons.radio_button_on, // Icons.favorite
    color: Colors.blueAccent, // Colors.red
    size: 35,
  );
  Icon secondIcon = Icon(
    Icons.radio_button_unchecked, // Icons.favorite_border
    color: Colors.grey,
    size: 35,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: ListView.builder(
            itemCount: itemCount,
            itemBuilder: (BuildContext context, int index) {
              return IconButton(
                icon: selected.elementAt(index) ? firstIcon : secondIcon,
                onPressed: () {
                  try {
                    // your code that you want this IconButton do
                    setState(() {
                      selected[index] = !selected.elementAt(index);
                    });
                    print('tap on ${index + 1}th IconButton ( change to : ');
                    print(selected[index] ? 'active' : 'deactive' + ' )');
                  } catch (e) {
                    print(e);
                  }
                },
              );
            }),
      ),
    );
  }
}
Naevus answered 19/10, 2020 at 14:9 Comment(4)
Thanks it works but when I change of pages and return on my home page, the Button which were selected are not. How I can save the button which are selected ?Metallize
you should define your List<bool> in global for accessibility everywhere. for example, you can move this to out of the classes and ext.Naevus
move your List<bool> out of calss in global and set initial value in initState with this lines in class : @override initState() { for (var i = 0; i < itemCount; i++) { selected.add(false); } super.initState(); }Naevus
I'm not sure to understand can you give me the example pleaseMetallize
N
1

the IconButton must be in StatefulWidget and use a flag for unselected icon and selected icon:

. . .

bool selected = false;
Icon first_icon = Icon(...);
Icon second_icon = Icon(...);

. . .

 IconButton(
    icon: selected
            ? first_icon 
            : second_icon,
    onPressed: () {
         try {
            // your code that you want this IconButton do
            setState(() {
                selected  = !selected;
            });
         } catch(e) {
             print(e);
         }  
    }),

for use in ListView:

. . .

List<bool> selected =  new List<bool>();
Icon first_icon = Icon(...);
Icon second_icon = Icon(...);

. . .

ListView.builder(
     controller: scrollController,
     primary: true,
     ...
     itemCount: _yourListViewLength,
     itemBuilder: (BuildContext context, int i) {
        selected.add(false);
        IconButton(
            icon: selected.elementAt(i)
                ? first_icon 
                : second_icon,
           onPressed: () {
             try {
                // your code that you want this IconButton do
                setState(() {
                    selected.elementAt(i) = !selected.elementAt(i);
                });
             } catch(e) {
                 print(e);
             }  
           }),
     },
 )

i hope this help you

Naevus answered 19/10, 2020 at 7:57 Comment(2)
It works but I have this Icon button in a ListView and when I click, it changes all the IconButtons ? How I can do for just change the Icon which is pressed.Metallize
you can selected change from bool to List<bool> with length same your ListView length. one selected for each element in ListViewNaevus
M
0

My code if you want : home_screen.dart

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../recyclerview/data.dart';
import 'package:watch/constants.dart';


class ListViewExample extends StatefulWidget {
  @override 
  State<StatefulWidget> createState() {
    return new ListViewExampleState();
  }
}

class ListViewExampleState extends State<ListViewExample>{
  bool addFavorite = false;
  Icon notFavorite = Icon(Icons.favorite_border, size: 25,);
  Icon inFavorite = Icon(Icons.favorite, size: 25,);
  List<Container> _buildListItemsFromItems(){
    return item.map((item){

      var container = Container(
        child: new Row(
          children: <Widget>[
            //Image
            new Container(
              margin: new EdgeInsets.all(5.0),
              child: new CachedNetworkImage(
                imageUrl: item.imageURL,
                height: MediaQuery.of(context).size.width / 4,
                width: MediaQuery.of(context).size.width / 2,
                fit: BoxFit.cover,
              ),
            ),
            //Text
            Expanded(
              child: new Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Spacer(),               
                //Titre
                Container(
                  padding: const EdgeInsets.only(bottom: 75.0, top: 5.0 ),
                  child: Text(
                    item.title,
                    style: kItemTitle,
                  ),
                ),
                //Decription
                Container(
                  padding: const EdgeInsets.only(left: 10.0, top: 5.0),
                  child:Text(
                    item.description,
                    style: kItemDescription,
                  ),
                ),
                //Favoris
                Spacer(),
                GestureDetector(
                  child: Container(
                    padding: const EdgeInsets.only(right: 10.0, top: 1.0),
                    child: addFavorite ? inFavorite : notFavorite,
                  ),
                  onTap: () {
                    setState(() {
                      addFavorite = !addFavorite;
                    });
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    );
  return container;
    }).toList();
  }

  //Scaffold Global

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
       appBar: AppBar(
         title: Text('Accueil', style: kAppBarStyle,),
          //backgroundColor: Colors.white,  
          elevation: 0,
       ),
       body: ListView(
      children: _buildListItemsFromItems(),
    ),
    );
  }
}

It is not an IconButton but just an Icon but it is working.

Metallize answered 19/10, 2020 at 11:56 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.