按下时如何更改 IconButton 的图标

Posted

技术标签:

【中文标题】按下时如何更改 IconButton 的图标【英文标题】:How change the Icon of an IconButton when it is pressed 【发布时间】:2021-02-01 16:05:14 【问题描述】:

我想知道如何在 IconButton 被按下时更改它的图标。 (Favorite_border 到收藏夹)。我尝试了一些东西,但它不起作用。 也许这很容易,但我是初学者,不太了解它是如何工作的。

更新

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


它是一个包含图像、文本和收藏按钮的 ListView,它工作正常。

【问题讨论】:

可能重复***.com/questions/50185357/… 请在一个最小的例子中向我们展示您尝试过的内容。否则我们帮不了你。 我已经发布了我的代码 这能回答你的问题吗? how to change icon color immediately after pressed in flutter? 【参考方案1】:

首先你需要一个布尔变量。

  bool toggle = false;

之后你可以像这样使用 IconButton:

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

【讨论】:

它可以工作,但我在 ListView 中有这个 Icon 按钮,当我点击时,它会更改所有 IconButtons 吗?我该怎么做才能改变按下的图标。【参考方案2】:

复制粘贴代码,它会工作:)

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


更新 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;
                  );
                );
          ),
    );
  

【讨论】:

它可以工作,但我在 ListView 中有这个 Icon 按钮,当我点击时,它会更改所有 IconButtons 吗?我该怎么做才能改变按下的图标。 添加了ListView.builder 部分。您可以复制粘贴代码,它将正常工作。不要忘记标记答案plz :) 按一下怎么让星星凸出来?【参考方案3】:

IconButton 必须在 StatefulWidget 中,并为未选中的图标和选中的图标使用一个标志:

。 . .

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

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

希望对你有帮助

【讨论】:

它可以工作,但我在 ListView 中有这个 Icon 按钮,当我点击时,它会更改所有 IconButtons 吗?我该怎么做才能改变按下的图标。 您可以选择从 bool 更改为 List,长度与您的 ListView 长度相同。为 ListView 中的每个元素选择一个【参考方案4】:

我的代码,如果你想要的话: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(),
    ),
    );
  


它不是一个 IconButton 而只是一个 Icon 但它正在工作。

【讨论】:

【参考方案5】:

自定义单选按钮(ListView 中的一些 IconButton 会更改其图标):

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

my_home_page.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 + 1th IconButton ( change to : ');
                    print(selected[index] ? 'active' : 'deactive' + ' )');
                   catch (e) 
                    print(e);
                  
                ,
              );
            ),
      ),
    );
  

【讨论】:

谢谢它的工作,但是当我改变页面并返回我的主页时,选择的按钮不是。如何保存被选中的按钮? 你应该在全局中定义你的 List 以便在任何地方访问。例如,您可以将其移出类和分机。 将您的 List 从全局中的 calss 中移出并在 initState 中设置初始值,并在类中使用以下行:@override initState() for (var i = 0; i 我不太明白你能给我举个例子吗

以上是关于按下时如何更改 IconButton 的图标的主要内容,如果未能解决你的问题,请参考以下文章

在悬停并按下时更改 QPushButton 图标

按下时更改 Android ListView 条目中的图标

在第二次按下时更改标签栏按钮的行为

在按钮按下时颤动旋转图标并带有动画

按下设备的主页键后,如何始终在图标按下时打开当前活动

在按下时查看:按下时更改背景颜色?如何显示正在按下视图?