我想在通过setState函数更新列表之后,将所选值从DropDown传递给它的父对象,然后通过构造函数传递给子对象。

因此,我希望可以从“限制”(UserOffers)的子级访问“下拉列表”中的选定值。

将数据从父级发送到子级实际上是有效的,但是仅当im通过构造函数将在父类中定义的数据传递给子级时= im不确定这是一种好方法。

现在,我正在使用提供程序来仅更新Dropdown上的数据,但我不知道如何传递它。

CountryProvider类:

class CountryProvider with ChangeNotifier {
  List<String> _items = [
    "Argentina",
    "Brazil",
    ...
   "Spain",
    "Switzerland",
  ];

  String _selectedItem;

  List<String> get items => _items;

  String get selected => _selectedItem;

  void setSelectedItem(String s) {
    _selectedItem = s;
    notifyListeners();
  }
}

CountryDropDown类:
class CountryDropDown extends StatefulWidget {
  @override
  _CountryDropDownState createState() => _CountryDropDownState();
}
class _CountryDropDownState extends State<CountryDropDown> {
  @override
  void initState() {
    super.initState();
  }
...
          ChangeNotifierProvider<CountryProvider>(
            create: (context) => CountryProvider(),
            child: Container(
              width: 215,
              child: Consumer<CountryProvider>(
                builder: (_, provider, __) {
                  return DropdownButton<String>(
                    hint: Text("Not selected"),
                    icon: Icon(Icons.flight),
                    value: dropdownValue,
                    onChanged: (String newValue) {
                      provider.setSelectedItem(newValue);
                      dropdownValue = provider.selected;
                      print(newValue);
                    },
                    items: provider.items
                        .map<DropdownMenuItem<String>>((String value) {
                      return DropdownMenuItem<String>(
                        value: value,
                        child: Text(value),
                      );
                    }).toList(),
                  );
...

和 parent :

限制类别:
class Restrictions extends StatefulWidget {
  @override
  _RestrictionsState createState() => _RestrictionsState();
}

class _RestrictionsState extends State<Restrictions> {
  @override
  void initState() {
    super.initState();
  }
...
Column(
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.only(left: 20),
                      child: FieldDropDown(),
                    ),
                    Container(
                      padding: EdgeInsets.only(top: 10),
                      margin: EdgeInsets.only(left: 20),
                      child: CountryDropDown(),
                    ),
                  ],
                ),
                Container(
                  child: DateSelector(),
                ),
              ],
            ),
            Container(
              child: UserOffers(
                country: selectedCountry,
                field: selectedField,
              ),
...

最佳答案

@Boras!您使用所有...为我做了很多工作。

我认为您需要将状态提升到小部件树的上方,以便当用户从下拉菜单中选择国家时UserOffers可以更改。

在下面完成示例应用程序。

请注意,我将模型类名称更改为SingleSelectCountry。该模型类的实例不是提供程序。该模型类的实例是提供者提供的。那里有一个重要的区别。

还要注意,所有小部件都扩展了StatelessWidget。通常,使用包提供程序可以避免使用StatefulWidget

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

// Model ---------------------------------------------------

class SingleSelectCountry with ChangeNotifier {
  final List<String> _items = <String>[
    "Argentina",
    "Belgium",
    "Brazil",
    "Denmark",
    "England",
    "France",
    "Finland",
    "Germany",
    "Holland",
    "Ireland",
    "Norway",
    "Poland",
    "Scotland",
    "Spain",
    "Sweden",
    "Switzerland",
    "Wales",
  ];

  String _selectedItem;

  UnmodifiableListView<String> get items {
    return UnmodifiableListView(this._items);
  }

  String get selected {
    return this._selectedItem;
  }

  set selected(final String item) {
    this._selectedItem = item;
    this.notifyListeners();
  }
}

// User Interface ------------------------------------------

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    // The provider has to be in the widget tree higher than
    // both `CountryDropDown` and `UserOffers`.
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<SingleSelectCountry>(
          create: (final BuildContext context) {
            return SingleSelectCountry();
          },
        ),
      ],
      child: Scaffold(
        appBar: AppBar(
          title: Text('My Home Page'),
        ),
        body: Restrictions(),
      ),
    );
  }
}

class Restrictions extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    return Column(
      children: <Widget>[
        CountryDropDown(),
        UserOffers(),
      ],
    );
  }
}

class CountryDropDown extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    return Consumer<SingleSelectCountry>(
      builder: (
        final BuildContext context,
        final SingleSelectCountry singleSelectCountry,
        final Widget child,
      ) {
        return DropdownButton<String>(
          hint: const Text("Not selected"),
          icon: const Icon(Icons.flight),
          value: singleSelectCountry.selected,
          onChanged: (final String newValue) {
            singleSelectCountry.selected = newValue;
          },
          items: singleSelectCountry.items.map<DropdownMenuItem<String>>(
            (final String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            },
          ).toList(),
        );
      },
    );
  }
}

class UserOffers extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    return Consumer<SingleSelectCountry>(
      builder: (
        final BuildContext context,
        final SingleSelectCountry singleSelectCountry,
        final Widget child,
      ) {
        return Text(singleSelectCountry.selected ?? '');
      },
    );
  }
}

关于flutter - Flutter-使用相同的提供程序更新下拉列表并将数据发送到另一个小部件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60092271/

10-14 10:29