繁体   English   中英

简单的DropdownButton不适用于新页面路由波动

[英]Simple DropdownButton not working on new page route flutter

我的应用程序很简单。

我有一个主页,您可以在其中按一个按钮来打开新的MaterialPageRoute。

在这个新的页面路线中,我有一个基本的下拉列表。

问题是,当我点击下拉菜单时,出现以下错误:

setState() or markNeedsBuild() called when widget tree was locked.
This Navigator widget cannot be marked as needing to build because the framework is locked.

下拉列表是“ FilterPage”类的成员。 仅当我将FilterPage放在新的页面路由中时,才会发生该错误。 例如,如果我使用一个新的FilterPage()作为主页,则一切运行正常。

复制此代码的所有代码如下。 谢谢您的关注!

import 'package:flutter/material.dart';

final Map<String,String> categoryLookup = {
  "business":"Accounting/Business",
  "science":"Science",
  "technology":"Technology"
};

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Link',
      home: new Home(),
      routes: <String, WidgetBuilder> {
        '/filter': (BuildContext context) => new FilterPage(),
      },
    );
  }

}

class Home extends StatefulWidget {
  @override
  createState() => new HomeState();
}

class HomeState extends State<Home> {

  @override
  Widget build(BuildContext context){
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Browse Jobs'),
        actions: <Widget>[
          new IconButton(
            icon: new Icon(Icons.search),
            onPressed: () => Navigator.of(context).pushNamed('/filter'),
          ),
        ],
      ),
      body: new Center(
        child: new Text("Home"),
      ),
    );
  }

}

class FilterPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    final GlobalKey<MyDropDownState> categoryKey = new GlobalKey<MyDropDownState>();
    final MyDropDown categoryDropdown = new MyDropDown(key: categoryKey, itemMap: categoryLookup);

    print("key: "+ categoryKey.toString());

    return new Scaffold(
      appBar : new AppBar(
        title: new Text('Filter Jobs'),
        actions: <Widget>[
          new IconButton(
            icon: new Icon(Icons.refresh),
            onPressed: () {
              print('Will reset dropdown using key');
            },
          ),
        ],
      ),
      body: new Container(
        padding: new EdgeInsets.all(20.0),
        child: new Column(
          children: <Widget>[
            categoryDropdown,
          ],
        ),
      ),
    );
  }
}

class MyDropDown extends StatefulWidget {

  MyDropDown({
    Key key,
    this.itemMap
  }) : super(key:key);

  final Map<String, String> itemMap;

  @override
  MyDropDownState createState() => new MyDropDownState();

}

class MyDropDownState extends State<MyDropDown> {

  String _selection;

  @override
  Widget build(BuildContext context) {
    return new DropdownButton(
      value: _selection,
      items: getDropItems(widget.itemMap),
      onChanged: (s) {
        setState(() {
          _selection = s;
        });
      },
      hint: new Text('None'),
    );
  }

  List<DropdownMenuItem> getDropItems(Map<String, String> itemMap){
    final List<DropdownMenuItem> itemList = [];
    itemMap.forEach(
        (key,value){
          itemList.add(new DropdownMenuItem<String>(value: key, child: new Text(value)));
        }
    );
    return itemList;
  }

}

要解决您的问题,请更改

class FilterPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
final GlobalKey<MyDropDownState> categoryKey = new .......
final MyDropDown categoryDropdown = new MyDropDown(key: categoryKey,.....

static final GlobalKey<MyDropDownState> categoryKey = new .....
final MyDropDown categoryDropdown = new MyDropDown(key: categoryKey,......

@override
Widget build(BuildContext context) {

也就是说,在build方法之外拉出可变声明,并使categoryKey为“ static”(添加static,因为在初始化程序中只能访问static成员)

发生错误是因为您在构建方法中声明了变量“ categoryKey ”和“ categoryDropdown ”。 当路由到FilterPage并调用build方法从而创建categoryKey的不同实例时,这会产生问题。

在您完成的打印中也可以看到相同的结果

“ print(” key:“ + categoryKey.toString());”

更改之前:

key: [LabeledGlobalKey<MyDropDownState>#4ef43]
key: [LabeledGlobalKey<MyDropDownState>#61c88]
key: [LabeledGlobalKey<MyDropDownState>#4eb6e]

更改后:

key: [LabeledGlobalKey<MyDropDownState>#ac21e]
key: [LabeledGlobalKey<MyDropDownState>#ac21e]
key: [LabeledGlobalKey<MyDropDownState>#ac21e]

如您所见,类别键在更改后将获得相同的代码。

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM