【问题标题】:Flutter Dropdown value not updating and UI not updating when submitting提交时 Flutter Dropdown 值未更新且 UI 未更新
【发布时间】:2022-12-30 01:59:17
【问题描述】:

我正在做一个 flutter 项目来展示一个 Scrumboard,这是我第一次使用 flutter。我有一个 TextButton,按下时会打开一个对话框。该对话框是一种表单,您可以在其中编辑有关 Scrum 任务的详细信息。我发现了两个问题。 1. 问题是当我使用下拉菜单并选择一个值时。该值不会更新。 2. 假设我编辑了一个 Scrum 任务,并从下拉菜单中将状态从“待办事项”设置为“进行中”并提交,UI 不会将该任务对象移动到“进行中”列。

我希望我提供的代码足够了,否则请告诉我。

Scrumboardscreen.dart

TextButton(
                      child: Text('Change'),
                      onPressed: () {
                        showDialog(
                            context: context,
                            builder: ((context) {
                              return AlertDialog(
                                title: Text('Task Informations'),
                                content: Form(
                                  key: _formKey,
                                  child: Column(
                                    children: [
                                      Text('Task Name'),
                                      TextFormField(
                                        controller: textscontrollers[0],
                                        decoration: InputDecoration(
                                          hintText: data[listIndex]
                                              .items[itemIndex]
                                              .taskName,
                                        ),
                                        validator: (text) {
                                          if (text == null || text.isEmpty) {
                                            return 'Task Name cant be empty';
                                          }
                                          return null;
                                        },
                                      ),
                                      Text('Task Description'),
                                      TextFormField(
                                        controller: textscontrollers[1],
                                        decoration: InputDecoration(
                                          hintText: data[listIndex]
                                              .items[itemIndex]
                                              .taskDescription,
                                        ),
                                        validator: (text) {
                                          if (text == null || text.isEmpty) {
                                            return 'Task Description cant be empty';
                                          }
                                          return null;
                                        },
                                      ),
                                      Text('Story Points'),
                                      TextFormField(
                                        controller: textscontrollers[2],
                                        decoration: InputDecoration(
                                          hintText: data[listIndex]
                                              .items[itemIndex]
                                              .storyPoints
                                              .toString(),
                                        ),
                                        validator: (text) {
                                          if (text == null || text.isEmpty) {
                                            return 'Story Points cant be empty';
                                          }
                                          return null;
                                        },
                                      ),
                                      Text('Task State'),
                                      DropdownButton<String>(
                                        value: data[listIndex]
                                            .items[itemIndex]
                                            .taskState,
                                        icon: const Icon(Icons.arrow_downward),
                                        elevation: 16,
                                        style: const TextStyle(
                                          color: Colors.blue,
                                        ),
                                        underline: Container(
                                          height: 2,
                                          color: Colors.blue,
                                        ),
                                        onChanged: (String? value) {
                                          setState(() {
                                            data[listIndex]
                                                .items[itemIndex]
                                                .taskState = value!;
                                          });
                                        },
                                        items: states
                                            .map<DropdownMenuItem<String>>(
                                                (String value) {
                                          return DropdownMenuItem<String>(
                                            value: value,
                                            child: Text(value),
                                          );
                                        }).toList(),
                                      ),
                                      ElevatedButton(
                                        onPressed: () {
                                          if (_formKey.currentState!
                                              .validate()) {
                                            _UpdateTask(data[listIndex]
                                                .items[itemIndex]);
                                            ScaffoldMessenger.of(context)
                                                .showSnackBar(const SnackBar(
                                                    content:
                                                        Text('Updated Task')));
                                            Navigator.of(context).pop();
                                          }
                                        },
                                        child: Text('Submit Changes'),
                                      )
                                    ],
                                  ),
                                ),
                              );
                            }));
                      },
                    ),

此方法在 Futurebuilder 中,并在 UI 上显示数据

Future<List<BoardPostColumn>> GetData() async {
    if (data.isEmpty) {
      data = await manager.GetData();
    }
    return data;
  }

更新方法

void _UpdateTask(BoardPost task) async {
    task.taskName = textscontrollers[0].text;
    task.taskDescription = textscontrollers[1].text;
    task.storyPoints = int.parse(textscontrollers[2].text);
    BoardPost result = await manager.UpdateTask(task);
    setState(() {
//My understanding that this would update the UI
     task = result;
      textscontrollers[0].clear();
      textscontrollers[1].clear();
      textscontrollers[2].clear();
    });
  }

经理班

Future<BoardPost> UpdateTask(BoardPost task) async {
    return handler.UpdateTask(task);
  }

ApiHandler.dart

Future<BoardPost> UpdateTask(BoardPost task) async {
    Response response = await post(
        Uri.parse('https://localhost:7252/api/ScrumTask/UpdateScrumTask'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(<String, dynamic>{
          'id': task.id,
          'taskName': task.taskName,
          'taskDescription': task.taskDescription,
          'storyPoints': task.storyPoints,
          'taskState': task.taskState
        }));
    if (response.statusCode == 200) {
      Map<String, dynamic> ScrumMap = jsonDecode(response.body);
      return BoardPost.fromJson(ScrumMap);
    } else {
      throw Exception('Failed to Update');
    }
  }
class BoardPost {
  int? id;
  String? taskName;
  String? taskDescription;
  int? storyPoints;
  String? taskState;

  BoardPost(
      {this.id,
      this.taskName,
      this.taskDescription,
      this.storyPoints,
      this.taskState});

  BoardPost.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    taskName = json['taskName'];
    taskDescription = json['taskDescription'];
    storyPoints = json['storyPoints'];
    taskState = json['taskState'];
  }

这里的这个类将显示所有数据

class BoardPostColumn {
  String title;
  List<BoardPost> items;

  BoardPostColumn({
    required this.title,
    required this.items,
  });
}

返回从 api 提供的数据的管理器类

Future<List<BoardPostColumn>> GetData() async {
    Response responseBody = await handler.GetData();
    List<BoardPostColumn> data = [];
    List<BoardPost> tasks = (json.decode(responseBody.body) as List)
        .map((data) => BoardPost.fromJson(data))
        .toList();
    data.add(BoardPostColumn(
        title: 'To do',
        items:
            tasks.where((e) => e.taskState?.toLowerCase() == 'todo').toList()));
    data.add(BoardPostColumn(
        title: 'In Progress',
        items: tasks
            .where((e) => e.taskState?.toLowerCase() == 'in progress')
            .toList()));
    data.add(BoardPostColumn(
        title: 'Done',
        items:
            tasks.where((e) => e.taskState?.toLowerCase() == 'done').toList()));
    return data;
  }

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    尝试在 showDialog 中使用 StatefulBuilder 来更新对话框 ui。

        showDialog(
          context: context,
          builder: (context) {
            return StatefulBuilder(builder: (context, setStateSB) => AlertDialog(...),)
          },
        );
    

    使用这个setStateSB作为setState来更新对话框ui,你可能需要在函数上传递这个setStateSB或者在函数调用结束时调用它setStateSB((){})。

    【讨论】:

      猜你喜欢
      • 2022-01-14
      • 2013-05-25
      • 1970-01-01
      • 2020-12-17
      • 2020-12-04
      • 1970-01-01
      • 2015-01-28
      • 2020-06-03
      • 1970-01-01
      相关资源
      最近更新 更多