简体   繁体   English

Flutter DropDownButton 即使在更新时也不会显示选定的值

[英]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.所以我创建了我自己的使用 DropDownButton class 的小部件,它曾经工作,它会以一种方式更新,在你 select 一个值之后,它会显示选定的值。 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.我重构了我的代码以涉及整个模型视图/视图模型技术,现在在你 select 列表中的一个值之后,它仍然只在你单击它后显示列表的默认第一个值。

Here is the code for my DropDownWidget class:这是我的 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.因此,从我看到的代码中,您正在构建方法中初始化变量,而您必须在 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.该项目正在更改,但 setstate 方法会将其重新分配给列表中的第一项。

as setstate will rebuild the the build method and you did assigned the items in the build method.因为 setstate 将重建构建方法,并且您确实在构建方法中分配了项目。 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(),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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