【问题标题】:Simple DropdownButton not working on new page route flutter简单的 DropdownButton 不适用于新页面路由颤动
【发布时间】:2018-09-04 22:55:29
【问题描述】:

我的应用很简单。

我有一个主页,您可以在其中按一个按钮打开一个新的 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() 作为 home,那么一切正常。

复制它的所有代码如下。谢谢你看这个!

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;
  }

}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    为了解决你的问题,改变

    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设为“静态”(加静态,因为在初始化器中只能访问静态成员)

    发生错误是因为您在构建方法中声明了变量“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]
    

    正如您在此处看到的,类别键在更改后得到相同的代码。

    希望这会有所帮助!

    【讨论】:

    • 你是个天才!感谢您的帮助和出色的解释。
    • 谢谢 :) 很高兴我能帮上忙!
    猜你喜欢
    • 2013-03-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    相关资源
    最近更新 更多