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

Flutter:如何通过Provider/ValueNotifier跨组件获取Dropdown值

用ValueNotifier或Provider实现Dropdown选中值传递(替代回调)

你当前通过回调函数实现了Dropdown选中值的跨组件传递,下面分别用ValueNotifier(Flutter原生轻量方案)和Provider(第三方状态管理包)两种方式替换原有逻辑,代码直接适配你的现有项目结构:


方案一:ValueNotifier实现(轻量无依赖)

ValueNotifier是Flutter自带的轻量状态管理工具,适合简单的跨组件状态同步,无需额外安装包。

1. 修改PropertyType组件

移除原有的onChanged回调,改为接收ValueNotifier<String>实例:

class PropertyType extends StatelessWidget { // 无需Stateful,状态交给ValueNotifier管理
  final ValueNotifier<String> propertyTypeNotifier;
  const PropertyType({
    super.key,
    required this.propertyTypeNotifier,
  });

  final List<String> _propertyTypeList = propertyType;

  @override
  Widget build(BuildContext context) {
    return ANPFormContainer(
      fieldTitle: 'Property Type',
      subTitle: 'အိမ်ခြံမြေအမျိုးအစား',
      child: FormBuilderDropdown<String>(
        name: 'a2-propertyType',
        initialValue: propertyTypeNotifier.value,
        items: _propertyTypeList
            .map(
              (itemValue) => DropdownMenuItem(
                value: itemValue,
                child: Text(itemValue),
              ),
            )
            .toList(),
        onChanged: (val) {
          if (val != null) {
            propertyTypeNotifier.value = val; // 直接更新ValueNotifier的值
          }
        },
      ),
    );
  }
}

2. 修改「添加新房产」页面(ANPTest)

创建ValueNotifier实例并传入子组件,提交时直接读取其值:

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

  @override
  State<ANPTest> createState() => _ANPTestState();
}

class _ANPTestState extends State<ANPTest> {
  final TextEditingController _propertyid = TextEditingController();
  final ValueNotifier<String> _propertyTypeNotifier = ValueNotifier('No Info');

  @override
  void dispose() {
    _propertyTypeNotifier.dispose(); // 销毁实例避免内存泄漏
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: ZayyanColorTheme.zayyanGrey,
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            PropertyID(propertyID: _propertyid),
            PropertyType(propertyTypeNotifier: _propertyTypeNotifier), // 传入ValueNotifier
            addVerticalSpacer(25),
            ANPNextButton(onPressed: _onpressed),
          ],
        ),
      ),
    );
  }

  _onpressed() {
    final anp = MdlFirestoreData(
            propertyid: _propertyid.text, 
            propertyType: _propertyTypeNotifier.value) // 直接读取选中值
        .toFirestore();
    FirebaseFirestore.instance.collection('Selling Posts').add(anp);
  }
}

方案二:Provider实现(适合复杂表单/多页面共享)

如果后续需要添加更多表单字段,或状态需要跨页面共享,推荐使用Provider包进行集中状态管理。

1. 添加Provider依赖

在pubspec.yaml中添加最新版本的Provider:

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.1.1 # 可替换为最新版本

2. 创建状态管理类

新建一个ChangeNotifier子类,统一管理表单状态(可后续扩展其他字段):

import 'package:flutter/foundation.dart';

class PropertyFormProvider extends ChangeNotifier {
  String _propertyType = 'No Info';
  String get propertyType => _propertyType;

  void updatePropertyType(String newType) {
    _propertyType = newType;
    notifyListeners(); // 通知所有监听组件更新UI
  }
}

3. 修改「添加新房产」页面(ANPTest)

用ChangeNotifierProvider包裹页面,提供状态实例:

import 'package:provider/provider.dart';

class ANPTest extends StatelessWidget {
  const ANPTest({super.key});

  final TextEditingController _propertyid = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => PropertyFormProvider(), // 创建状态实例
      child: Scaffold(
        backgroundColor: ZayyanColorTheme.zayyanGrey,
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              PropertyID(propertyID: _propertyid),
              const PropertyType(), // 无需传参,直接从Provider获取状态
              addVerticalSpacer(25),
              ANPNextButton(onPressed: () => _onpressed(context)),
            ],
          ),
        ),
      ),
    );
  }

  _onpressed(BuildContext context) {
    final formProvider = Provider.of<PropertyFormProvider>(context, listen: false);
    final anp = MdlFirestoreData(
            propertyid: _propertyid.text, 
            propertyType: formProvider.propertyType)
        .toFirestore();
    FirebaseFirestore.instance.collection('Selling Posts').add(anp);
  }
}

4. 修改PropertyType组件

通过Provider.of获取状态并更新:

import 'package:provider/provider.dart';

class PropertyType extends StatelessWidget {
  const PropertyType({super.key});

  final List<String> _propertyTypeList = propertyType;

  @override
  Widget build(BuildContext context) {
    final formProvider = Provider.of<PropertyFormProvider>(context);
    return ANPFormContainer(
      fieldTitle: 'Property Type',
      subTitle: 'အိမ်ခြံမြေအမျိုးအစား',
      child: FormBuilderDropdown<String>(
        name: 'a2-propertyType',
        initialValue: formProvider.propertyType,
        items: _propertyTypeList
            .map(
              (itemValue) => DropdownMenuItem(
                value: itemValue,
                child: Text(itemValue),
              ),
            )
            .toList(),
        onChanged: (val) {
          if (val != null) {
            formProvider.updatePropertyType(val); // 调用状态更新方法
          }
        },
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Saw Tha Wah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:10:55