Flutter-使用相同的提供程序来更新下拉列表并将数据发送到另一个小部件

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

我想将选定值从DropDown传递到其父级,然后通过构造函数传递给子级,在setState函数更新列表之后。

所以,我希望可以从“限制”(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(),
                  );
...

和父母:

限制类:

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,
              ),
...
flutter mobile dart provider state-management
1个回答
0
投票

@@ Boras!所有的...,都为我做了很多工作。

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

下面完整的示例应用程序。

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

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

class SingleSelectCountry with ChangeNotifier {
  final List<String> _items = [
    "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 ?? '');
      },
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.