You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:Hero弹窗组件调用Provider报错致应用冻结问题排查

问题分析与解决方案

核心问题

  1. Provider类型不匹配:主组件中StreamProvider提供的是单个MyUser?对象,但弹窗组件中尝试获取List<MyUser?>类型的Provider,这会触发找不到对应Provider的异常,直接导致应用冻结。
  2. 冗余列表操作:弹窗里对用户列表的循环复制完全多余,可能触发不必要的重绘逻辑。
  3. 空值处理缺失:未过滤用户列表中的空对象,容易导致DropdownMenuItem出现空文本或空值,引发渲染异常。

修复步骤

1. 修正Provider层级与类型

如果需要在弹窗中获取用户列表,需在主组件中添加对应的StreamProvider,确保弹窗上下文能获取到正确的数据流:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const Hyttekos());
}

class Hyttekos extends StatelessWidget {
  const Hyttekos({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        // 保留原单个用户的Provider
        StreamProvider<MyUser?>.value(
          initialData: null,
          value: AuthService().user,
        ),
        // 添加用户列表的StreamProvider(假设AuthService有users数据流)
        StreamProvider<List<MyUser?>>.value(
          initialData: [],
          value: AuthService().users,
        ),
      ],
      child: const MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}

2. 优化弹窗用户列表处理

移除冗余的列表复制,添加空值过滤,避免异常:

@override
Widget build(BuildContext context) {
  // 获取用户列表Provider
  var board = Provider.of<List<MyUser?>>(context);
  // 过滤空用户,避免Dropdown出现空内容
  List<MyUser?> members = board.where((user) => user != null).toList();

  return Center(
    child: Padding(
      padding: const EdgeInsets.all(32.0),
      child: Hero(
        tag: _heroAddTag,
        createRectTween: (begin, end) => RectTween(begin: begin, end: end),
        child: Material(
          color: Colors.white,
          elevation: 2,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
          child: SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  DropdownButton<String>(
                    value: _dropDownActivity,
                    hint: const Text("选择活动"),
                    onChanged: _dropDownCallActivity,
                    items: activities.map((String value) {
                      return DropdownMenuItem(
                        value: value,
                        child: Text(value),
                      );
                    }).toList(),
                  ),
                  DropdownButton<String>(
                    value: _dropDownMember,
                    hint: const Text("选择成员"),
                    onChanged: _dropDownCallMember,
                    items: members.map((MyUser? value) {
                      return DropdownMenuItem(
                        value: value?.uid ?? "",
                        child: Text(value?.name ?? ""),
                      );
                    }).toList(),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    ),
  );
}

3. 优化Dropdown的空值逻辑

修正_dropDownCallMember中的冗余判断,同时给Dropdown添加hint属性提升体验:

void _dropDownCallMember(String? selectedValue) {
  setState(() {
    _dropDownMember = selectedValue;
  });
  print(_dropDownMember);
}

4. 清理冗余参数

弹窗构造函数中的membersToShow参数未被使用,建议删除:

class addActivityPopupCard extends StatefulWidget {
  const addActivityPopupCard({Key? key}) : super(key: key);

  @override
  State<addActivityPopupCard> createState() => _addActivityPopupCardState();
}

内容的提问来源于stack exchange,提问作者Aslak Aarflot Jønsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 08:25:01