flutter - 使用提供程序时 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);
},
)
],
),
),
);
}
}
解决方案
这发生在Task
对象没有通知更改时,
尝试
TextFormField(
initialValue: task.taskText,
onChanged: (c) {
task.taskText = c,
Provider.of<TaskData>(context, listen: false).notifyListeners();
}
),
推荐阅读
- javascript - 我在@Component 中遇到主机问题
- entity-framework - 在 EF 核心中禁用跟踪返回跟踪错误
- c# - 无法解析符号“notnull”
- apache-spark - 调用 split() 函数时出现“split”的 Pyspark 错误不在列表中
- netcdf - 连接具有不同变量的 netcdf 文件 - 使用 nco
- vue.js - 嵌套样式在我的组件样式中不起作用
- java - JSON Schema 中使用 Jackson 注释的自定义属性关键字
- ios - iOS 13:带有 LeftView 间距问题的 UITextField - Xcode 11
- typescript - Typescript - 从另一种类型创建详尽的元组类型
- mongodb - 发生异常。MongoDartError (MongoDart Error: Invalid scheme in uri: mongodb+srv://) with flutter