2

我猜我错过了一些简单的东西,但我已经在这几天尝试了所有可能的解决方案。我们如何处理 listview.builder 中的下拉选择?是否可以将下拉按钮值存储在 List-String- 中?

我正在创建一个基于 XML 模板的动态表单,并具有下拉菜单、复选框、输入等。编辑:在页面加载时解析 XML 之前,我不知道需要哪些小部件。因此尝试将动态创建的小部件列表传递给 Listview.builder。

下面的代码是一个未能更新的基本示例。

在这里欣赏任何建议。

import 'package:flutter/material.dart';

class FormEG extends StatefulWidget {
  @override
  _FormEGState createState() => new _FormEGState();
}

class _FormEGState extends State<FormEG> {
  List<String> _listValues;
  List<DropdownMenuItem<String>> _items;
  List<Widget> _widgets;

  @override
  void initState() {
    _listValues = new List<String>();
    _listValues.add("b");

    _items = new List<DropdownMenuItem<String>>();
    _items.add(new DropdownMenuItem(child: Text("a"), value: "a"));
    _items.add(new DropdownMenuItem(child: Text("b"), value: "b"));
    _items.add(new DropdownMenuItem(child: Text("c"), value: "c"));
    _items.add(new DropdownMenuItem(child: Text("d"), value: "d"));

    _widgets = new List<Widget>();
    _widgets.add(new DropdownButton<String>(
      value: _listValues[0],
      items: _items,
      onChanged: (String newValue) {
        setState(() {
          _listValues[0] = newValue;
        });
      },
    ));
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new ListView.builder(
          itemCount: _widgets.length,
          itemBuilder: (context, index) {
          return _widgets[index];
          },
        ));
      }
  }
4

3 回答 3

1

我最终List<Widget>用 statefulbuilder 包装了每个下拉小部件(in ),因此当从每个小部件调用 setstate 时,仅更新该小部件,但如果需要,仍然可以更新整个树。这样,根据 anmol.majhail 注释从构建中调用 setState。

import 'package:flutter/material.dart';

class FormEG extends StatefulWidget {
  @override
  _FormEGState createState() => new _FormEGState();
}

class _FormEGState extends State<FormEG> {
  List<String> _listValues;
  List<DropdownMenuItem<String>> _items;
  List<Widget> _widgets;

  @override
  void initState() {
    _listValues = new List<String>();
    setDefaults();
    setWidgets();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    print("built");
    return new Scaffold(
        body: new ListView.builder(
          itemCount: _widgets.length,
          itemBuilder: (context, index) {
        return _widgets[index];
      },
    ));
  }

  void setDefaults() {
    _listValues.add("b");
  }

  void setWidgets() {
    setMenuItems();
    _widgets = new List<Widget>();
    _widgets.add(
      new StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return new DropdownButton<String>(
            value: _listValues[0],
            items: _items,
            onChanged: (String newValue) {
              setState(() {
                _listValues[0] = newValue;
              });
            },
          );
        },
      ),
    );
  }

  void setMenuItems() {
    _items = new List<DropdownMenuItem<String>>();
    _items.add(new DropdownMenuItem(child: Text("a"), value: "a"));
    _items.add(new DropdownMenuItem(child: Text("b"), value: "b"));
    _items.add(new DropdownMenuItem(child: Text("c"), value: "c"));
    _items.add(new DropdownMenuItem(child: Text("d"), value: "d"));
  }
}
于 2018-12-06T11:53:59.100 回答
0

您可以尝试仅使用列表并动态更新列表,然后设置状态。

ListView(
                  shrinkWrap: true,
                  scrollDirection: Axis.vertical,
                  children: dropDownList),
            ),

然后根据触发器/事件对其进行更新。

 _buildDropDownList() {
     if (dropDownEnabled) {
       setState (() {
         dropDownList.addAll([1,2,,4,5])
       });
       } else {
        setState (() {
         dropDownList = [];
      });   
    }
于 2020-06-12T06:30:42.747 回答
0

遵循代码效果很好。因为SetSate再次调用 Build 方法并再次DropdownButton绘制。在您的代码DropdownButton中放置在 _widgets[0] 值处,并且此值在代码周期中保持静态。即使在调用之后SetState它也将保持不变 - 因为SetState不会更新 _widgets[0] 值 - 它只会再次调用 Build Method。

@override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new ListView.builder(
      itemCount: _widgets.length,
      itemBuilder: (context, index) {
        return DropdownButton<String>(
          value: _listValues[0],
          items: _items,
          onChanged: (newValue) {
            setState(() {
              _listValues[0] = newValue;
            });
          },
        );
      },
    ));
  }
于 2018-12-06T08:39:21.760 回答