4

I have DropDownButton in ListView.Builder whenever I selected from dropdown it gives on change value but doesn't reflect on 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;
    }

This is my ListView Item widget

  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(''),
                )
              ],
            ),
          ),
        ],
      );
    }

This method is calling in ListView Item widget

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

All Above methods are declared inside build(BuildContext context)

enter image description here

Farhana Naaz Ansari
  • 7,524
  • 26
  • 65
  • 105

3 Answers3

9

I have created one variable with selectedItemValue to store selected value in DropdownButton, Before i set default value to None all item.

    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

Amit Prajapati
  • 13,525
  • 8
  • 62
  • 84
  • 1
    You have no idea how this helped me. This code made my day. Thanks a Lot, @Amit Prajapati bro. It worked exactly as expected. – Akash Neeli Sep 28 '21 at 12:17
0

If all of this is inside the build when you call setState this will reset the values including the variables.

In your case _dropDownWarranty = getDropDownWarranty(); is setting the value of _dropDownWarranty to getDropDownWarranty(); everytime you call setState regardless of what it is set to in the the onChanged.

I would recommend moving the _dropDownWarranty = getDropDownWarranty(); outside of the build but within the class still. In fact, I would recommend moving function outside of the build method but keeping them in the class as a rule otherwise they will rerun every time you call setState!

This example shows how to set the value but not having it inside the build method https://stackoverflow.com/a/54948635/4644407

George Herbert
  • 390
  • 2
  • 10
0

You can try using expansion tile for this which is provided by flutter it.

ExpansionTile(
    title: Text(artistData.artistName),
        children: [
               ListTile(
                    leading: Image(
                    image: NetworkImage(artistData.artworkUrl100),
                        ),
                    title: Text(artistData.collectionName),
                      subtitle: Text(artistData.description),
                    )
                  ],
               );
satsin06
  • 1
  • 2