首页 > 解决方案 > 使用提供程序时 Flutter 小部件未更新

问题描述

我正在尝试在我的颤振应用程序中实现提供程序,但有点卡住了。

它基本上是一个任务列表。您应该能够双击现有任务并编辑文本。任务文本下方是一个计数器,它显示任务文本的长度,但在我输入时它永远不会更新。任何想法为什么?

任务.dart

class Task {
  String taskText;
  bool completed;
  String id = UniqueKey().toString();
  Task({
    this.taskText = '',
    this.completed = false,
  });
  void toggle() {
    completed = !completed;
  }
}

任务数据.dart

import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:task_management/model/task.dart';

class TaskData with ChangeNotifier {
  List<Task> _tasks = [];
  UnmodifiableListView<Task> get tasks => UnmodifiableListView(_tasks);

  void addTask(Task task) {
    int index = _tasks.indexWhere((element) => element.id == task.id);

    if (index == -1) {
      _tasks.add(task);
    } else {
      _tasks[index] = task;
    }
    notifyListeners();
  }

  void toggleTask(Task task) {
    task.toggle();
    notifyListeners();
  }

  void removeTask(Task task) {
    _tasks.remove(task);
    notifyListeners();
  }
}

主要.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'model/task_data.dart';
import 'screens/home.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => TaskData(),
      child: MaterialApp(
        title: 'Provider Demo',
        theme: ThemeData(
          primarySwatch: Colors.green,
        ),
        home: Home(),
      ),
    );
  }
}

主页.dart

import 'package:flutter/material.dart';

import 'package:task_management/screens/task_list.dart';
import 'task_form.dart';

class Home extends StatelessWidget {
// create the appbar
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('GeeksforGeeks'),
      ),
      body: Container(
        padding: EdgeInsets.all(20),
        child: TaskList(),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(
          Icons.add,
        ),
        onPressed: () {
          Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) => TaskForm(
                        taskIndex: -1,
                      )));
        },
      ),
    );
  }
}

task_list.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:task_management/model/task_data.dart';

import 'task_form.dart';

class TaskList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<TaskData>(builder: (context, data, child) {
      return ListView.builder(
        scrollDirection: Axis.vertical,
        shrinkWrap: true,
        itemCount: data.tasks.length,
        itemBuilder: (context, index) {
          final task = data.tasks[index];

          // gesture detection
          return GestureDetector(
            onLongPress: () => data.removeTask(task),
            onDoubleTap: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => TaskForm(
                            taskIndex: index,
                          )));
            },
            child: Container(
              margin: EdgeInsets.only(bottom: 10),
              padding: EdgeInsets.fromLTRB(12, 5, 8, 5),
              width: double.infinity,
              decoration: BoxDecoration(color: Colors.black12, borderRadius: BorderRadius.circular(8)),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  // text field
                  Text(
                    task.taskText,
                    style: TextStyle(decoration: task.completed ? TextDecoration.lineThrough : null, fontSize: 16, fontWeight: FontWeight.bold),
                  ),

                  // switch case
                  Switch(
                    value: task.completed,
                    onChanged: (c) => data.toggleTask(task),
                  ),
                ],
              ),
            ),
          );
        },
      );
    });
  }
}

task_form.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:task_management/model/task.dart';
import 'package:task_management/model/task_data.dart';

class TaskForm extends StatelessWidget {
  final int taskIndex;
  TaskForm({required this.taskIndex});

  @override
  Widget build(BuildContext context) {
    TaskData taskProvider = Provider.of<TaskData>(context);
    Task task = taskIndex != -1 ? taskProvider.tasks[taskIndex] : Task();
    return Scaffold(
      appBar: AppBar(
        title: Text('Task Form'),
      ),
      body: Container(
        padding: EdgeInsets.all(18),
        child: Column(
          children: [
            TextFormField(
              initialValue: task.taskText,
              onChanged: (c) => task.taskText = c,
            ),
            Text(task.taskText.length.toString()),
            // add button
            ElevatedButton(
              child: Text(
                'Submit',
              ),

              // assign action
              onPressed: () {
                Provider.of<TaskData>(context, listen: false).addTask(task);

                Navigator.pop(context);
              },
            )
          ],
        ),
      ),
    );
  }
}

标签: flutterflutter-provider

解决方案


这发生在Task对象没有通知更改时,

尝试

 TextFormField(
              initialValue: task.taskText,
              onChanged: (c) {
               task.taskText = c,
               Provider.of<TaskData>(context, listen: false).notifyListeners();
               } 
            ),

推荐阅读