0
votes

Comment changer l'icône d'un IconButton lorsqu'il est enfoncé

Je veux savoir comment je peux changer l'icône d'un IconButton lorsqu'il est pressé. (Favorite_border à Favorite). J'ai essayé quelque chose mais ça ne marche pas. C'est peut-être facile mais je suis débutant et je ne comprends pas très bien comment cela fonctionne.

Mise à jour

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);
                    });
                    },
                ),
              ],
            ),
          ),
        ],
      ),
    );
    }
    )
  );
}
}

C'est un ListView avec des images, des textes et le bouton favori et cela fonctionne très bien.


4 commentaires

probablement dupliquer stackoverflow.com/questions/50185357/...


Veuillez nous montrer ce que vous avez essayé dans un exemple minimal. Sinon, nous ne pouvons pas vous aider.


J'ai posté mon code


Est-ce que cela répond à votre question? comment changer la couleur de l'icône immédiatement après avoir appuyé sur le flutter?


5 Réponses :


2
votes

Vous avez d'abord besoin d'une variable booléenne.

   IconButton(
          icon: toggle
              ? Icon(Icons.favorite_border)
              : Icon(
                  Icons.favorite,
                ),
          onPressed: () {
            setState(() {
              // Here we changing the icon.
              toggle = !toggle;
            });
          }),

Après cela, vous pouvez utiliser IconButton comme ceci:

  bool toggle = false;


1 commentaires

Cela fonctionne mais j'ai ce bouton Icon dans un ListView et quand je clique, cela change tous les IconButtons? Comment je peux faire pour changer simplement l'icône sur laquelle vous appuyez.



1
votes

Copiez collez le code et cela fonctionnera :)

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;
                  });
                });
          }),
    );
  }
}

Mise à jour du code pour ListView

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;
              });
            }),
      ),
    );
  }
}


2 commentaires

Cela fonctionne mais j'ai ce bouton Icon dans un ListView et quand je clique, cela change tous les IconButtons? Comment je peux faire pour changer simplement l'icône sur laquelle vous appuyez.


Ajout de la partie ListView.builder . Vous pouvez copier-coller le code, cela fonctionnera très bien. N'oubliez pas de marquer la réponse plz :)



1
votes

le IconButton doit être dans StatefulWidget et utiliser un indicateur pour l'icône non sélectionnée et l'icône sélectionnée:

. . .

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);
             }  
           }),
     },
 )

. . .

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

à utiliser dans ListView:

. . .

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

. . .

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

j'espère que cela vous aidera


4 commentaires

Cela fonctionne mais j'ai ce bouton Icon dans un ListView et quand je clique, cela change tous les IconButtons? Comment je peux faire pour changer simplement l'icône sur laquelle vous appuyez.


vous pouvez sélectionner le changement de booléen à List <bool> avec la même longueur que votre ListView. un sélectionné pour chaque élément dans ListView


Pouvez-vous me donner un exemple du code merci


je poste le code dans une nouvelle réponse



0
votes

Mon code si vous voulez: 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(),
    ),
    );
  }
}

Ce n'est pas un IconButton mais juste une icône mais cela fonctionne.


0 commentaires

1
votes

bouton radio personnalisé (certains IconButton dans ListView qui changent leurs icônes):

fichier main.dart :

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);
                  }
                },
              );
            }),
      ),
    );
  }
}

Fichier my_home_page.dart :

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'),
    );
  }
}


6 commentaires

Merci ça marche mais quand je change de page et que je reviens sur ma page d'accueil, les Button qui ont été sélectionnés ne le sont pas. Comment puis-je enregistrer les boutons sélectionnés?


vous devez définir votre List <bool> en global pour une accessibilité partout. par exemple, vous pouvez déplacer ceci hors des classes et ext.


déplacez votre List <bool> hors de cals dans global et définissez la valeur initiale dans initState avec ces lignes dans la classe: @override initState () {for (var i = 0; i <itemCount; i ++) {selected.add (false); } super.initState (); }


Je ne suis pas sûr de comprendre pouvez-vous me donner l'exemple s'il vous plaît


vérifier le code supérieur, je le modifie


ça marche merci!