将选定的DropDown值从有状态小部件返回到MainPage有状态小部件

时间:2020-03-11 01:16:56

标签: flutter drop-down-menu

我在将DropDown(状态小部件)的下拉列表中选择的字符串值返回/传递回RestApiManager(状态小部件)中的MainPage时遇到问题。

主页:

class MainPage extends StatefulWidget {
  MainPage({Key key}) : super(key: key);

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

class _MainPageState extends State<MainPage> {

...

@override
  Widget build(BuildContext context) {
    var futureBuilder = FutureBuilder<CompanyWorth>(
      future: RestApiManager().fetchCompanyWorth('${_selectedCompany.name}'), // this is where im trying to return to
   ...

设置:

class DropDown extends StatefulWidget {
  DropDown() : super();

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

class Company {
  int id;
  String name;

  Company(this.id, this.name);

  static List<Company> getCompanies() {
    return <Company>[
      Company(1, 'Apple'),
      Company(2, 'Google'),
      ...
    ];
  }
}

class DropDownState extends State<DropDown> {
  //
  List<Company> _companies = Company.getCompanies();
  List<DropdownMenuItem<Company>> _dropdownMenuItems;
  Company _selectedCompany;

  @override
  void initState() {
    _dropdownMenuItems = buildDropdownMenuItems(_companies);
    _selectedCompany = _dropdownMenuItems[0].value;
    super.initState();
  }

  List<DropdownMenuItem<Company>> buildDropdownMenuItems(List companies) {
    List<DropdownMenuItem<Company>> items = List();
    for (Company company in companies) {
      items.add(
        DropdownMenuItem(
          value: company,
          child: Text(company.name),
        ),
      );
    }
    return items;
  }

  onChangeDropdownItem(Company selectedCompany) {
    setState(() {
      _selectedCompany = selectedCompany;
    });
  }

  @override
  Widget build(BuildContext context) {
     ...
            children: <Widget>[
              Text("Select a company"),
              DropdownButton(
                value: _selectedCompany,
                items: _dropdownMenuItems,
                onChanged: onChangeDropdownItem,
              ),
              Text('Selected: ${_selectedCompany.name}'), // i want to return the string from here to mainpage
            ],
          ),
    ...
}

任何解决方案/建议都将不胜感激。

1 个答案:

答案 0 :(得分:1)

您可以在下面复制粘贴运行完整代码
假设DropDown位于其他页面

步骤1:在MainPage中使用result = await Navigator.push,然后调用setState
步骤2:在DropDown页面中,使用Navigator.pop(context, _selectedCompany.name);将参数传递回MainPage
代码段

onPressed: () async {
          result = await Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => DropDown()),
          );

          setState(() {});
        },

RaisedButton(
                onPressed: () {
                  Navigator.pop(context, _selectedCompany.name);
                },
                child: Text('Go back!'),
              ),    

工作演示

enter image description here

完整代码

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String result = "";

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  fetchCompanyWorth(String result) {
    return Future.value(result);
  }

  @override
  Widget build(BuildContext context) {
    print("build");
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FutureBuilder<String>(
              future: fetchCompanyWorth(
                  result), // a previously-obtained Future<String> or null
              builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.none:
                    return Text('Press button to start.');
                  case ConnectionState.active:
                  case ConnectionState.waiting:
                    return Text('Awaiting result...');
                  case ConnectionState.done:
                    if (snapshot.hasError)
                      return Text('Error: ${snapshot.error}');
                    return Text('Result: ${snapshot.data}');
                }
                return null; // unreachable
              },
            ),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          result = await Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => DropDown()),
          );

          setState(() {});
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class DropDown extends StatefulWidget {
  DropDown() : super();

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

class Company {
  int id;
  String name;

  Company(this.id, this.name);

  static List<Company> getCompanies() {
    return <Company>[
      Company(1, 'Apple'),
      Company(2, 'Google'),
    ];
  }
}

int selectedCompanyIndex = 0;

class DropDownState extends State<DropDown> {
  //
  List<Company> _companies = Company.getCompanies();
  List<DropdownMenuItem<Company>> _dropdownMenuItems;
  Company _selectedCompany;

  @override
  void initState() {
    _dropdownMenuItems = buildDropdownMenuItems(_companies);
    _selectedCompany = _dropdownMenuItems[selectedCompanyIndex].value;
    super.initState();
  }

  List<DropdownMenuItem<Company>> buildDropdownMenuItems(List companies) {
    List<DropdownMenuItem<Company>> items = List();
    for (Company company in companies) {
      items.add(
        DropdownMenuItem(
          value: company,
          child: Text(company.name),
        ),
      );
    }
    return items;
  }

  onChangeDropdownItem(Company selectedCompany) {
    setState(() {
      _selectedCompany = selectedCompany;
      selectedCompanyIndex = _companies.indexOf(_selectedCompany);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Column(
        children: <Widget>[
          Text("Select a company"),
          DropdownButton(
            value: _selectedCompany,
            items: _dropdownMenuItems,
            onChanged: onChangeDropdownItem,
          ),
          Text('Selected: ${_selectedCompany.name}'),
          RaisedButton(
            onPressed: () {
              Navigator.pop(context, _selectedCompany.name);
            },
            child: Text('Go back!'),
          ),

          // i want to return the string from here to mainpage
        ],
      ),
    ));
  }
}