在Flutter中ListView内的下拉框

4

我在ListView.Builder中有一个DropDownButton,每当我从下拉列表中进行选择时,它都会给出更改后的值,但在UI上没有反映出来。

 List _warranty = ["NONE","1 YEAR", "2 YEAR"];
 List<DropdownMenuItem<String>> getDropDownWarranty() {
      List<DropdownMenuItem<String>> items = new List();
      for (String str in _warranty) {
        items.add(new DropdownMenuItem(
            value: str,
            child: new Text(
              str,
              style: TextStyle(color: Colors.white, fontFamily: 'semibold'),
            )));
      }
      return items;
    }

这是我的ListView项目小部件。
  Widget item(AsyncSnapshot<CartBean> snapshot, int index) {
      String _current = "";
      return Column(
        children: <Widget>[
          Container(
            height: 40,
            decoration: BoxDecoration(color: MyColors.cartback),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.end,
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Container(
                  width: SizeConfig.screenWidth / 1.7,
                  padding: EdgeInsets.all(SizeConfig.blockSizeHorizontal * 2),
                  decoration: BoxDecoration(
                    color: MyColors.colorLightPrimary,
                  ),
                  child: snapshot.data.data[index].lcwInfo.length > 0
                      ? Theme(
                    data: Theme.of(context).copyWith(
                        brightness: Brightness.dark,
                        canvasColor: MyColors.colorPrimary),

                    child: dropDown(snapshot.data.data[index].lcwInfo,
                        _current,index), // Your Dropdown Code Here,
                  )
                      : FlatButton(
                    onPressed: () {},
                    padding: EdgeInsets.all(0),
                    child: Text(
                      "EXTEND WARRANTY",
                      style: TextStyle(
                          color: Colors.grey[300],
                          fontFamily: "semibold"),
                    ),
                  ),
                ),
                FlatButton.icon(
                  onPressed: () {
                    removeCartItemService(
                        snapshot.data.data[index].productId, index);
                  },
                  icon: Image.asset(
                    'assets/icons/cancel.png',
                    width: 28,
                    height: 28,
                  ),
                  label: Text(''),
                )
              ],
            ),
          ),
        ],
      );
    }

这个方法在 ListView 的子项小部件中调用。

 Widget dropDown(List<LcwInfo> list, String _current,int index) {
      List<DropdownMenuItem<String>> _dropDownWarranty;
      _dropDownWarranty = getDropDownWarranty();
      _current = _dropDownWarranty[0].value;

      if (list.length > 0) {
        return DropdownButtonHideUnderline(
          child: DropdownButton<String>(
            value: _dropDownWarranty[0].value,
            items: _dropDownWarranty,
            onChanged: (String onValue) {
              debugPrint("CURRENT VALUE:----------${onValue}");
              updateWarrantyService(index,onValue,list[0]);
              setState(() {
                _dropDownWarranty[0] = onValue as DropdownMenuItem<String>;
              });
            },
          ),
        );
      }
    }

所有上述方法都在 build(BuildContext context) 中声明。 enter image description here
3个回答

9

我创建了一个变量 selectedItemValue 来存储在 DropdownButton 中选择的值,在设置默认值为 None 之前,所有项目都没有选中。

    class ListViewDemo extends StatefulWidget {
    @override
    State<StatefulWidget> createState() {
        return ListViewDemoState();
    }
    }

    class ListViewDemoState extends State<ListViewDemo> {
    List<String> selectedItemValue = List<String>();

    @override
    void initState() {
        // TODO: implement initState
        super.initState();
    }

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
            title: Text("ListView"),
            ),
            body: Column(
            children: <Widget>[
                Expanded(
                child: ListView.builder(
                    itemCount: 20,
                    itemExtent: 50.0,
                    itemBuilder: (BuildContext context, int index) {
                        for (int i = 0; i < 20; i++) {
                        selectedItemValue.add("NONE");
                        }
                        return DropdownButton(
                        value: selectedItemValue[index].toString(),
                        items: _dropDownItem(),
                        onChanged: (value) {
                            selectedItemValue[index] = value;
                            setState(() {});
                        },
                        hint: Text('Select Gender'),
                        );
                    }),
                )
            ],
            ));
    }
    }

    List<DropdownMenuItem<String>> _dropDownItem() {
    List<String> ddl = ["NONE", "1 YEAR", "2 YEAR"];
    return ddl
        .map((value) => DropdownMenuItem(
                value: value,
                child: Text(value),
            ))
        .toList();
    }

enter image description here


1
你不知道这对我有多大帮助。这段代码让我的一天变得美好了。非常感谢,@Amit Prajapati兄弟。它完全按照预期工作。 - Akash Neeli

0
你可以尝试使用Flutter提供的ExpansionTile来实现这个功能。
ExpansionTile(
    title: Text(artistData.artistName),
        children: [
               ListTile(
                    leading: Image(
                    image: NetworkImage(artistData.artworkUrl100),
                        ),
                    title: Text(artistData.collectionName),
                      subtitle: Text(artistData.description),
                    )
                  ],
               );

0

如果所有这些都在调用setState时位于build内部,那么这将重置值,包括变量。

在您的情况下,_dropDownWarranty = getDropDownWarranty();每次调用setState时都将_dropDownWarranty的值设置为getDropDownWarranty();,而不考虑在onChanged中它的值是什么。

我建议将_dropDownWarranty = getDropDownWarranty();移到build外部,但仍在类内部。实际上,我建议将函数移出build方法,但是将它们保留在类中作为一条规则,否则每次调用setState时它们都会重新运行!

此示例显示如何设置值,但不要将其放在build方法内https://dev59.com/-VUM5IYBdhLWcg3wIddd#54948635


我移动了所有与dropDown相关的代码,但仍然没有效果。 - Farhana Naaz Ansari
实际上,我的所有代码都被放在了构建方法之外,但我在SO上找到了一个解决方案,建议我将代码放在构建小部件内。 - Farhana Naaz Ansari
@FarhanaNaazAnsari 你好,我也遇到了同样的问题。我想在列表项内部添加下拉菜单。 - Sachin Suthar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接