使用按钮将图标添加到列表并使用 Provider 状态管理主动更新 UI

Posted

技术标签:

【中文标题】使用按钮将图标添加到列表并使用 Provider 状态管理主动更新 UI【英文标题】:Adding an Icon to a List using a button and actively updating UI using Provider state management 【发布时间】:2021-03-18 11:18:42 【问题描述】:

我想在 UI 更新后使用 Flutter 提供者状态管理将图标添加到列表中。 我成功地使用浮动按钮添加了一个图标,并通过打印新的列表长度来确认结果。这可确保将图标添加到列表中,但不会更新新添加图标的 UI。片段如下

  @override
  _MedicalCosmeticsDetailsPageState createState() =>
      _MedicalCosmeticsDetailsPageState();


class _MedicalCosmeticsDetailsPageState
    extends State<MedicalCosmeticsDetailsPage> 
  @override
  Widget build(BuildContext context) 
    Size size = MediaQuery.of(context).size;
    return ChangeNotifierProvider<GridIcons>(
      create: (context) => GridIcons(),
      child: SafeArea(
        child: Scaffold(
          appBar: AppBar(
            automaticallyImplyLeading: true,
            iconTheme: IconThemeData(color: Colors.purple),
            title: Text(
              'xyz',
              style: TextStyle(color: Colors.purple),
            ),
            backgroundColor: Colors.transparent,
            elevation: size.width * 0.05,
            actions: [
              Padding(
                padding: EdgeInsets.only(right: size.width * 0.01),
                child: IconButton(
                  icon: Icon(
                    Icons.search,
                  ),
                  onPressed: () ,
                ),
              ),
            ],
          ),
          body: GridViewPage(),
          floatingActionButton: Consumer<GridIcons>(
            builder: (context, myIcons, _) 
              return FloatingActionButton(
                child: Icon(Icons.add),
                onPressed: () 
                  print(myIcons.iconList.length);
                  myIcons.addIcon();
                ,
              );
            ,
          ),
        ),
      ),
    );
  

```//floating button for adding an ICON

```class GridIcons with ChangeNotifier 
  List<IconData> iconList = [
    Icons.ac_unit,
    Icons.search,
    Icons.arrow_back,
    Icons.hdr_on_sharp,
  ];

  addIcon<IconData>() 
    iconList.add(Icons.sentiment_dissatisfied);
    notifyListeners();
  

  getIconList<IconData>() 
    return iconList;
  

```//Function for icon addition

类 GridViewPage 扩展 StatelessWidget @覆盖 小部件构建(BuildContext 上下文) 列表_iconList = GridIcons().getIconList();

return ChangeNotifierProvider<GridIcons>(
  create: (context) => GridIcons(),
  child: Consumer<GridIcons>(
    builder: (context, myIcon, child) 
      return GridView.builder(
        itemCount: _iconList.length,
        padding: EdgeInsets.all(8.0),
        gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 250.0),
        itemBuilder: (BuildContext context, int index) 
          print('_buildGridViewBuilder $index');
          return Card(
            color: Colors.purple.shade300,
            margin: EdgeInsets.all(8.0),
            child: InkWell(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Icon(
                    _iconList[index],
                    size: 48.0,
                    color: Colors.purple.shade100,
                  ),
                  Divider(),
                  Text(
                    'Index $index',
                    textAlign: TextAlign.center,
                    style: GoogleFonts.dmSans(
                      fontSize: 16,
                      color: Colors.white,
                    ),
                  ),
                ],
              ),
              onTap: () 
                print('Row: $index');
              ,
            ),
          );
        ,
      );
    ,
  ),
);


The icon doesn't appear in the UI although an icon is added to the Icon List.

【问题讨论】:

【参考方案1】:

您可以在下面复制粘贴运行完整代码 第 1 步:在GridViewPage 中,您不需要ChangeNotifierProvider 第 2 步:删除 List _iconList = GridIcons().getIconList(); 第 3 步:使用 myIcon.iconList.lengthmyIcon.iconList[index] 代码sn-p

class GridViewPage extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    //List _iconList = GridIcons().getIconList();

    return Consumer<GridIcons>(
      builder: (context, myIcon, child) 
        return GridView.builder(
          itemCount: myIcon.iconList.length,
     ...
     Icon(
         myIcon.iconList[index],
         size: 48.0,

工作演示

完整代码

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';

class MedicalCosmeticsDetailsPage extends StatefulWidget 
  @override
  _MedicalCosmeticsDetailsPageState createState() =>
      _MedicalCosmeticsDetailsPageState();


class _MedicalCosmeticsDetailsPageState
    extends State<MedicalCosmeticsDetailsPage> 
  @override
  Widget build(BuildContext context) 
    Size size = MediaQuery.of(context).size;
    return ChangeNotifierProvider<GridIcons>(
      create: (context) => GridIcons(),
      child: SafeArea(
        child: Scaffold(
          appBar: AppBar(
            automaticallyImplyLeading: true,
            iconTheme: IconThemeData(color: Colors.purple),
            title: Text(
              'xyz',
              style: TextStyle(color: Colors.purple),
            ),
            backgroundColor: Colors.transparent,
            elevation: size.width * 0.05,
            actions: [
              Padding(
                padding: EdgeInsets.only(right: size.width * 0.01),
                child: IconButton(
                  icon: Icon(
                    Icons.search,
                  ),
                  onPressed: () ,
                ),
              ),
            ],
          ),
          body: GridViewPage(),
          floatingActionButton: Consumer<GridIcons>(
            builder: (context, myIcons, _) 
              return FloatingActionButton(
                child: Icon(Icons.add),
                onPressed: () 
                  print(myIcons.iconList.length);
                  myIcons.addIcon();
                ,
              );
            ,
          ),
        ),
      ),
    );
  


class GridIcons with ChangeNotifier 
  List<IconData> iconList = [
    Icons.ac_unit,
    Icons.search,
    Icons.arrow_back,
    Icons.hdr_on_sharp,
  ];

  addIcon<IconData>() 
    iconList.add(Icons.sentiment_dissatisfied);
    notifyListeners();
  

  getIconList<IconData>() 
    return iconList;
  


class GridViewPage extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    //List _iconList = GridIcons().getIconList();

    return Consumer<GridIcons>(
      builder: (context, myIcon, child) 
        return GridView.builder(
          itemCount: myIcon.iconList.length,
          padding: EdgeInsets.all(8.0),
          gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: 250.0),
          itemBuilder: (BuildContext context, int index) 
            print('_buildGridViewBuilder $index');
            return Card(
              color: Colors.purple.shade300,
              margin: EdgeInsets.all(8.0),
              child: InkWell(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Icon(
                      myIcon.iconList[index],
                      size: 48.0,
                      color: Colors.purple.shade100,
                    ),
                    Divider(),
                    Text(
                      'Index $index',
                      textAlign: TextAlign.center,
                      style: GoogleFonts.dmSans(
                        fontSize: 16,
                        color: Colors.white,
                      ),
                    ),
                  ],
                ),
                onTap: () 
                  print('Row: $index');
                ,
              ),
            );
          ,
        );
      ,
    );
  


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: MedicalCosmeticsDetailsPage());
  

【讨论】:

以上是关于使用按钮将图标添加到列表并使用 Provider 状态管理主动更新 UI的主要内容,如果未能解决你的问题,请参考以下文章

将样式表和图标添加到 QStyleOptionButton

将 ActionSheet 按钮链接到 TableView

如何在颤动中从列表中删除项目时重新加载列表

如何在 jQuery Mobile 拆分按钮列表项的两个按钮上添加图标?

如何将svg图标添加到带有文本的按钮

如何将最大化按钮添加到浮动 QDockWidget?