如何让datacell中包含的iconbutton根据状态显示不同的图标?

问题描述 投票:0回答:1

我使用分页数据表在数据单元中包含几个图标按钮。单击图标按钮后,我修改了rows[index]['status']的值。我希望 iconbutton 的图标根据 rows[index]['status'] 的值显示。


    import 'package:flutter/material.dart';
    
    List<Map<String, dynamic>> devData() {
      List<Map<String, dynamic>> data = [];
      for (var i = 1; i < 15; i++) {
        data.add({
          'username': 'account$i',
          'nickname': i % 2 == 0 ? 'Peter$i' : 'Charles$i',
          'status': i % 2 == 0 ? 0 : 1,
          'group': i % 2 == 0 ? 2 : 3,
        });
      }
      return data;
    }
    
    List<Map<String, dynamic>> rows = devData();
    
    
    class UserManagePage extends StatefulWidget {
      const UserManagePage({super.key});
    
      @override
      State<StatefulWidget> createState() => UserManagePageState();
    }
    
    class UserManagePageState extends State<UserManagePage> {
      UserManagePageState() {
        rows = devData();
      }
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
              leading: IconButton(
                hoverColor: Colors.transparent,
                onPressed: () {
                  Navigator.pop(context);
                },
                icon: const Icon(Icons.arrow_back_ios_new),
                iconSize: 16,
                color: const Color.fromRGBO(100, 100, 100, 0.5),
              ),
              centerTitle: true,
              automaticallyImplyLeading: false,
              backgroundColor: WidgetStateColor.transparent,
              title: const Text('用户管理',
                  style: TextStyle(
                      fontFamily: 'AlimamaFangYuanTi', fontSize: 18, fontWeight: FontWeight.w900))),
          body: Container(
              padding: const EdgeInsets.all(5),
              alignment: const Alignment(0, 0),
              child: PaginatedDataTable(
                horizontalMargin: 5,
                columnSpacing: 30,
                header: Row(children: [
                  IconButton(
                      onPressed: () {
                        showDialog(
                            context: context,
                            builder: (context) {
                              return const UserAdd();
                            });
                      },
                      icon: const Icon(Icons.person_add_alt_1))
                ]),
                columns: const [
                  DataColumn(label: Flexible(child: Center(child: Text('Account')))),
                  DataColumn(label: Flexible(child: Center(child: Text('Username')))),
                  DataColumn(label: Flexible(child: Center(child: Text('Group')))),
                  DataColumn(label: Flexible(child: Center(child: Text('Operation'))))
                ],
                source: UserManageDate(context: context),
              )),
        );
      }
    }
    
    class UserManageDate extends DataTableSource {
      BuildContext context;
    
      UserManageDate({required this.context});
    
      @override
      DataRow? getRow(int index) {
        List<String> groups = ['Super Admin', 'Admin', 'Doctor', 'Nurse'];
        return DataRow(cells: [
          DataCell(Text('${rows[index]['username']}')),
          DataCell(Text('${rows[index]['nickname']}')),
          DataCell(Text(groups[rows[index]['group']])),
          DataCell(
              Flex(
                direction: Axis.horizontal,
                children: [
                  IconButton(
                    onPressed: () {},
                    icon: const Icon(
                      Icons.edit,
                      size: 20,
                      color: Colors.green,
                    ),
                  ),
                  //edit
                  IconButton(
                    onPressed: () {
                      rows[index]['status'] = rows[index]['status'] == 1 ? 0 : 1;
                      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                          content: Text(rows[index]['status'] == 1 ? 'Enabled' : 'Disabled'),
                          action: SnackBarAction(label: 'Action', onPressed: () {}),
                          duration: const Duration(milliseconds: 500)));
                    },
                    icon: Icon(
                      rows[index]['status'] == 1 ? Icons.lock : Icons.lock_open_rounded,
                      size: 20,
                      color: rows[index]['status'] == 1 ? Colors.blue : Colors.grey,
                    ),
                  ),
                  //enable/disable
                  IconButton(
                    onPressed: () {},
                    icon: const Icon(
                      Icons.delete,
                      size: 20,
                      color: Colors.grey,
                    ),
                  )
                  //delete:soft delete
                ],
              ), onTap: () {
            print('11111222');
          })
        ]);
      }
    
      @override
      // TODO: implement isRowCountApproximate
      bool get isRowCountApproximate => false;
    
      @override
      // TODO: implement rowCount
      int get rowCount => rows.length;
    
      @override
      // TODO: implement selectedRowCount
      int get selectedRowCount => 0;
    }

这就是我的全部代码。

IconButton(
                onPressed: () {
                  rows[index]['status'] = rows[index]['status'] == 1 ? 0 : 1;
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                      content: Text(rows[index]['status'] == 1 ? 'Enabled' : 'Disabled'),
                      action: SnackBarAction(label: 'Action', onPressed: () {}),
                      duration: const Duration(milliseconds: 500)));
                },
                icon: Icon(
                  rows[index]['status'] == 1 ? Icons.lock : Icons.lock_open_rounded,
                  size: 20,
                  color: rows[index]['status'] == 1 ? Colors.blue : Colors.grey,
                ),
              ),

1.点击此按钮时更新rows[index]['status']值,但屏幕不更新

flutter state updates iconbutton paginateddatatable
1个回答
0
投票

没有

setState
,当数据发生改变时,需要使用setState修改状态,否则页面无法刷新,不过你用的是无状态组件,所以不能使用setState,所以我推荐使用
provider
进行管理,下面是对你的代码进行了重写的演示

import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'package:provider/provider.dart';

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

class UserDataProvider extends ChangeNotifier {
  List<Map<String, dynamic>> _rows = [];

  UserDataProvider() {
    _initializeData();
  }

  List<Map<String, dynamic>> get rows => _rows;

  void _initializeData() {
    for (var i = 1; i < 15; i++) {
      _rows.add({
        'username': 'account$i',
        'nickname': i % 2 == 0 ? 'Peter$i' : 'Charles$i',
        'status': i % 2 == 0 ? 0 : 1,
        'group': i % 2 == 0 ? 2 : 3,
      });
    }
    notifyListeners();
  }

  void updateStatus(int index) {
    _rows[index]['status'] = _rows[index]['status'] == 1 ? 0 : 1;
    notifyListeners();
  }
}

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

  @override
  State<StatefulWidget> createState() => UserManagePageState();
}

class UserManagePageState extends State<UserManagePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          leading: IconButton(
            hoverColor: Colors.transparent,
            onPressed: () {
              Navigator.pop(context);
            },
            icon: const Icon(Icons.arrow_back_ios_new),
            iconSize: 16,
            color: const Color.fromRGBO(100, 100, 100, 0.5),
          ),
          centerTitle: true,
          automaticallyImplyLeading: false,
          backgroundColor: Colors.transparent,
          title: const Text('用户管理',
              style: TextStyle(
                  fontFamily: 'AlimamaFangYuanTi',
                  fontSize: 18,
                  fontWeight: FontWeight.w900))),
      body: Container(
          padding: const EdgeInsets.all(5),
          alignment: const Alignment(0, 0),
          child: Consumer<UserDataProvider>(
            builder: (context, userDataProvider, child) {
              return PaginatedDataTable(
                horizontalMargin: 5,
                columnSpacing: 30,
                header: Row(children: [
                  IconButton(
                      onPressed: () {
                        showDialog(
                            context: context,
                            builder: (context) {
                              return AlertDialog(
                                  title: const Text('Add User'),
                                  content: const Text('Add User'),
                                  actions: [
                                    TextButton(
                                        onPressed: () {
                                          Navigator.pop(context);
                                        },
                                        child: const Text('Cancel')),
                                    TextButton(
                                        onPressed: () {
                                          Navigator.pop(context);
                                        },
                                        child: const Text('Add'))
                                  ]);
                            });
                      },
                      icon: const Icon(Icons.person_add_alt_1))
                ]),
                columns: const [
                  DataColumn(
                      label: Flexible(child: Center(child: Text('Account')))),
                  DataColumn(
                      label: Flexible(child: Center(child: Text('Username')))),
                  DataColumn(
                      label: Flexible(child: Center(child: Text('Group')))),
                  DataColumn(
                      label: Flexible(child: Center(child: Text('Operation'))))
                ],
                source: UserManageData(userDataProvider.rows, context),
              );
            },
          )),
    );
  }
}

class UserManageData extends DataTableSource {
  final List<Map<String, dynamic>> rows;
  final BuildContext context;

  UserManageData(this.rows, this.context);

  @override
  DataRow? getRow(int index) {
    List<String> groups = ['Super Admin', 'Admin', 'Doctor', 'Nurse'];
    return DataRow(cells: [
      DataCell(Text('${rows[index]['username']}')),
      DataCell(Text('${rows[index]['nickname']}')),
      DataCell(Text(groups[rows[index]['group']])),
      DataCell(
          Flex(
            direction: Axis.horizontal,
            children: [
              IconButton(
                onPressed: () {},
                icon: const Icon(
                  Icons.edit,
                  size: 20,
                  color: Colors.green,
                ),
              ),
              //edit
              IconButton(
                onPressed: () {
                  Provider.of<UserDataProvider>(context, listen: false)
                      .updateStatus(index);
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                      content: Text(
                          rows[index]['status'] == 1 ? 'Enabled' : 'Disabled'),
                      action: SnackBarAction(label: 'Action', onPressed: () {}),
                      duration: const Duration(milliseconds: 500)));
                },
                icon: Icon(
                  rows[index]['status'] == 1
                      ? Icons.lock
                      : Icons.lock_open_rounded,
                  size: 20,
                  color: rows[index]['status'] == 1 ? Colors.blue : Colors.grey,
                ),
              ),
              //enable/disable
              IconButton(
                onPressed: () {},
                icon: const Icon(
                  Icons.delete,
                  size: 20,
                  color: Colors.grey,
                ),
              )
              //delete:soft delete
            ],
          ), onTap: () {
        print('11111222');
      })
    ]);
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => rows.length;

  @override
  int get selectedRowCount => 0;
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // return MaterialApp(
    //   home: BlocProvider(
    //     create: (_) => ColorBloc(),
    //     child: UserManagePage(),
    //   ),
    // );
    return MaterialApp(
      home:  ChangeNotifierProvider(
        create: (context) => UserDataProvider(),
        child: UserManagePage(),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.