简体   繁体   中英

Flutter DropDownButton won't display selected value even when I update it

So I created my own widget that uses the DropDownButton class and it used to work, it would update in a way where after you select a value, it would display the selected value. I refactored my code to involve the whole model-view/viewmodel technique and now after you select a value from the list it still just displays the default first value of the list after you click it.

Here is the code for my DropDownWidget class:

class DropDownWidget extends StatefulWidget {
  //const DropDownWidget({Key? key}) : super(key: key);

  List<String> dropdownOptions = [];
  String? dropdownValue;

  DropDownWidget(List<String> options) {
    dropdownOptions = options;
    dropdownValue = dropdownOptions.isNotEmpty ? dropdownOptions[0] : null;
  }

  @override
  State<DropDownWidget> createState() => _DropDownWidgetState();
}

class _DropDownWidgetState extends State<DropDownWidget>
    with TickerProviderStateMixin {
  late AnimationController controller;

  @override
  void initState() {
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 1),
    )..addListener(() {
        setState(() {});
      });
    controller.repeat(reverse: true);
    super.initState();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    var dropdownOptions = widget.dropdownOptions;
    var dropdownValue = widget.dropdownValue;
    if (dropdownOptions.isEmpty) {
      return LinearProgressIndicator(
        value: controller.value, //0.75,
        color: const Color(0xFFFFA663),
        backgroundColor: const Color(0x3498DBA5),
      );
    }
    return DropdownButton<String>(
      value: dropdownValue, //?? dropdownOptions[0],
      icon: const Icon(
        Icons.agriculture_rounded,
        color: Color(0xFF773608), //Color(0xFF2E7D32), //Colors.green,
      ),
      elevation: 16,
      underline: Container(
        height: 2,
        color: vo.shade200,
      ),
      onChanged: (String? newValue) {
        setState(() {
          dropdownValue = newValue!;
          print(newValue);
        });
      },
      items: dropdownOptions.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }
}

Let me know if any more code is needed.

So from the code i see is that you are intializing the varialbles in the build method, instead you have to do it in the initState.

Why was the item not getting changed:

the item was getting changed but the setstate method would reasign it to the 1st item from the list.

as setstate will rebuild the the build method and you did assigned the items in the build method. So that was the reason it was not changing.

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: DropDownWidget(['one', 'two']),
      ),
    );
  }
}

class DropDownWidget extends StatefulWidget {
  //const DropDownWidget({Key? key}) : super(key: key);

  List<String> dropdownOptions = [];
  String? dropdownValue;

  DropDownWidget(List<String> options) {
    dropdownOptions = options;
    dropdownValue = dropdownOptions.isNotEmpty ? dropdownOptions[0] : null;
  }

  @override
  State<DropDownWidget> createState() => _DropDownWidgetState();
}

class _DropDownWidgetState extends State<DropDownWidget>
    with TickerProviderStateMixin {
  late AnimationController controller;
  late List<String> dropdownOptions;
  late String? dropdownValue;

  @override
  void initState() {
    dropdownOptions = widget.dropdownOptions;
    dropdownValue = widget.dropdownValue;
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 1),
    )..addListener(() {
        setState(() {});
      });
    controller.repeat(reverse: true);
    super.initState();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (dropdownOptions.isEmpty) {
      return LinearProgressIndicator(
        value: controller.value, //0.75,
        color: const Color(0xFFFFA663),
        backgroundColor: const Color(0x3498DBA5),
      );
    }
    return DropdownButton<String>(
      value: dropdownValue, //?? dropdownOptions[0],
      icon: const Icon(
        Icons.agriculture_rounded,
        color: Color(0xFF773608), //Color(0xFF2E7D32), //Colors.green,
      ),
      elevation: 16,
      underline: Container(
        height: 2,
        color: Colors.black,
      ),
      onChanged: (String? newValue) {
        setState(() {
          dropdownValue = newValue!;
          print(newValue);
        });
      },
      items: dropdownOptions.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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