flutter 当我点击一个瓷砖时 Flink 所有瓷砖

n3schb8v  于 2023-06-24  发布在  Flutter
关注(0)|答案(1)|浏览(124)

我有以下组件。一切都工作得很好,除了当我想点击一个瓷砖,所有的瓷砖 Flink 。如果我注解掉setState(),那么颜色不会发生变化。我还没有看到其他人在stackoverflow上有同样的问题。
如果有其他方法可以做到这一点,如使用第三个包让我知道。
有可能实现这样的改变吗?
欢迎任何帮助

class CompanyUserListWidget extends StatefulWidget {
  String companyId;
  CompanyUserListWidget({super.key, required this.companyId});

  @override
  State<CompanyUserListWidget> createState() => _CompanyUserListWidgetState();
}

class _CompanyUserListWidgetState extends State<CompanyUserListWidget> {
  late bool _isLoading = false;
  final CompanyUserFirebaseCloudStorage _companyInviteReposatory =
      CompanyUserFirebaseCloudStorage();
  final UserFirebaseCloudStorage _userReposatory = UserFirebaseCloudStorage();
  late String _companyId;
  List<int> _selectedUsersIndexes =
      []; // Track the selection state for each tile

  @override
  void initState() {
    _companyId = widget.companyId;
    super.initState();
  }

  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('test')),
        body: Column(
          children: [
            Expanded(
                child: StreamBuilder<List<CloudCompanyUser>>(
              stream:
                  _companyInviteReposatory.getCompanyUsersStream(_companyId),
              builder: (BuildContext context,
                  AsyncSnapshot<List<CloudCompanyUser>> snapshot) {
                if (snapshot.hasError) {
                  print(snapshot.error);
                  return Text('Something went wrong');
                }
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return const Center(child: CircularProgressIndicator());
                }
                return ListView.builder(
                  itemCount: snapshot.data!.length,
                  itemBuilder: (BuildContext context, int index) {
                    final companyUser = snapshot.data![index];
                    return _buildUserCompanyTile(companyUser, index);
                  },
                );
              },
            )),
          ],
        ));
  }

  _buildUserCompanyTile(companyUser, int index) {
    bool isSelected = _selectedUsersIndexes
        .contains(index); // Track the selection state of the tile

    return FutureBuilder(
      future: findUserById(companyUser.user_id),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            return const Text('Error fetching data');
          }
          return ListTile(
            title: Text(snapshot.data.name),
            subtitle: Text(snapshot.data.email),
            trailing: isSelected
                ? Icon(Icons.check)
                : null, // Add the check mark icon

            onTap: () {
              if (isSelected) {
                _selectedUsersIndexes.remove(index);
              } else {
                _selectedUsersIndexes.add(index);
              }
              setState(() {});
            },
            tileColor: isSelected
                ? Colors.green
                : null, // Change the color based on selection state
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }

  // Future<String?>
  Future<CloudUser?> findUserById(userId) async {
    return await _userReposatory.findUserById(userId);
  }

  onNewCompany() {
    // Navigator.push(
    //   context,
    //   MaterialPageRoute(builder: (context) => CompaniesEdit()),
    // );
  }
}
pprl5pva

pprl5pva1#

出现此行为的可能原因是**_buildUserCompanyTile内的FutureBuilder小部件导致在状态更新时重新生成列表切片。
解决方案是,您可以修改代码,将tile widget分成单独的
StatefulWidget**,并在列表重建时使用AutomaticKeepAliveClientMixin维护每个tile的状态。
更新示例:

class _CompanyUserListWidgetState extends State<CompanyUserListWidget> {
  late bool _isLoading = false;
  final CompanyUserFirebaseCloudStorage _companyInviteReposatory =
      CompanyUserFirebaseCloudStorage();
  final UserFirebaseCloudStorage _userReposatory = UserFirebaseCloudStorage();
  late String _companyId;
  List<int> _selectedUsersIndexes = [];

  @override
  void initState() {
    _companyId = widget.companyId;
    super.initState();
  }

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('test')),
      body: Column(
        children: [
          Expanded(
            child: StreamBuilder<List<CloudCompanyUser>>(
              stream: _companyInviteReposatory.getCompanyUsersStream(_companyId),
              builder: (BuildContext context, AsyncSnapshot<List<CloudCompanyUser>> snapshot) {
                if (snapshot.hasError) {
                  print(snapshot.error);
                  return Text('Something went wrong');
                }
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return const Center(child: CircularProgressIndicator());
                }
                return ListView.builder(
                  itemCount: snapshot.data!.length,
                  itemBuilder: (BuildContext context, int index) {
                    final companyUser = snapshot.data![index];
                    return CompanyUserTile(
                      companyUser: companyUser,
                      isSelected: _selectedUsersIndexes.contains(index),
                      onSelect: () => _toggleUserSelection(index),
                    );
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  _toggleUserSelection(int index) {
    setState(() {
      if (_selectedUsersIndexes.contains(index)) {
        _selectedUsersIndexes.remove(index);
      } else {
        _selectedUsersIndexes.add(index);
      }
    });
  }
}

class CompanyUserTile extends StatefulWidget {
  final CloudCompanyUser companyUser;
  final bool isSelected;
  final Function() onSelect;

  const CompanyUserTile({
    required this.companyUser,
    required this.isSelected,
    required this.onSelect,
  });

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

class _CompanyUserTileState extends State<CompanyUserTile> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context); // Ensure that the state is kept alive

    return FutureBuilder<CloudUser?>(
      future: findUserById(widget.companyUser.user_id),
      builder: (BuildContext context, AsyncSnapshot<CloudUser?> snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            return const Text('Error fetching data');
          }
          final user = snapshot.data;
          return ListTile(
            title: Text(user?.name ?? ''),
            subtitle: Text(user?.email ?? ''),
            trailing: widget.isSelected ? Icon(Icons.check) : null,
            onTap: widget.onSelect,
            tileColor: widget.isSelected ? Colors.green : null,
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }

  Future<CloudUser?> findUserById(String userId) async {
    return await _userReposatory.findUserById(userId);
  }
}

相关问题