dart 使用riverpod提供程序时,ListView不呈现小部件

aydmsdu9  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(108)

我写了一个应用程序使用flutter添加项目列表(使用simpleDialog),并显示因此在ListView项目时,你添加上。问题是,只有当我移动到另一个页面时,列表才会更新,并且它们到达列表页面,因此数据在那里。我只是不知道怎么列清单重新渲染……
这是我声明的提供程序

@riverpod
List<Task> tasks(TasksRef ref) => [];

字符串
这是我的小部件如何预设列表(任务)

class TasksScreen extends StatefulHookConsumerWidget {
  const TasksScreen({super.key});

  @override
  ConsumerState<TasksScreen> createState() => _TasksScreenState();
}

class _TasksScreenState extends ConsumerState<TasksScreen> {
  @override
  Widget build(BuildContext context) {
    List<model.Task> tasks = ref.read(tasksProvider);
    List<Task> list = [];
    list = [...test(tasks)];

    return ProviderScope(
        child: Scaffold(
      body: ListView.builder(
        itemBuilder: (context, index) {
          return Task(task: ref.read(tasksProvider)[index]);
        },
        itemCount: ref.read(tasksProvider).length,
      ),
    ));
  }

  List<Task> test(List<model.Task> list) {
    List<Task> tasks = [];

    for (var i = 0; i < list.length; i++) {
      tasks.add(Task(task: list[i]));
    }

    return tasks;
  }
}


非常感谢帮助!
我期望提供者的改变会导致呈现页面并显示列表的列表

vmjh9lq9

vmjh9lq91#

您应该使用watch而不是read,因为当状态如文档中所述发生变化时,read不会重新构建小部件

class TaskListNotifier extends StateNotifier<List<model.Task>> {
    TaskListNotifier() : super([]); // initial state
    void add(model.Task) {
        state.add(model.Task);
        state = [...state]; // this will notify and rebuild the UI
    }
}

final tasksProvider = StateNotifierProvider<TaskListNotifier, List<model.Task>>((ref) {
  return TaskListNotifier();
});

class TasksScreen extends StatefulHookConsumerWidget {
  const TasksScreen({super.key});

  @override
  ConsumerState<TasksScreen> createState() => _TasksScreenState();
}

class _TasksScreenState extends ConsumerState<TasksScreen> {
  @override
  Widget build(BuildContext context) {
    List<model.Task> tasks = ref.watch(tasksProvider);

    return ProviderScope(
        child: Scaffold(
      body: ListView.builder(
        itemBuilder: (context, index) {
          return GestureDetector(
          onTap: () {
            ref.read(tasksProvider.notifier).add(tasks[index]);
          },
          child: Task(task: tasks[index]),
          );
        },
        itemCount: tasks.length,
      ),
    ));
  }
}

字符串

mxg2im7a

mxg2im7a2#

对不起,我从来没有使用过Riverpod软件包,所以我不能直接给予你这个建议,你可能要等待一个不同的答案。
但是对于要触发重建的构建方法,应该使用watch而不是read
我不知道riverpod是否也有一些 Package 器,或者像ChangeNotifier这样的帮助类,你需要把你的列表 Package 进去。
转换为默认提供程序包后,代码段的工作示例如下所示:

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

class TaskStorage with ChangeNotifier {
  List<ModelTask> _myTasks = [];

  void add(ModelTask newTask) {
    _myTasks.add(newTask);
    notifyListeners();
  }

  UnmodifiableListView<ModelTask> get tasks => UnmodifiableListView<ModelTask>(_myTasks);
}

class ModelTask {
  int someData = 10;
}

class Task extends StatelessWidget {
  final ModelTask task;

  const Task({
    required this.task,
  });

  @override
  Widget build(BuildContext context) {
    return Text("task: ${task.someData}");
  }
}

class TasksScreen extends StatefulWidget {
  const TasksScreen({super.key});

  @override
  State createState() => _TasksScreenState();
}

class _TasksScreenState extends State<TasksScreen> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: ListView.builder(
            itemBuilder: (context, index) {
              return Task(task: context.watch<TaskStorage>().tasks[index]);
            },
            itemCount: context.watch<TaskStorage>().tasks.length,
          ),
        ),
        ElevatedButton(
          onPressed: () => context.read<TaskStorage>().add(ModelTask()),
          child: Text("ADD"),
        ),
      ],
    );
  }
}

void main() => runApp(
      MaterialApp(
        home: Scaffold(
          backgroundColor: Colors.green,
          appBar: AppBar(),
          body: ChangeNotifierProvider<TaskStorage>(
            create: (BuildContext context) {
              return TaskStorage();
            },
            child: const TasksScreen(),
          ),
        ),
      ),
    );

字符串
也许这个还能帮到你我建议查看riverpod包的文档。

相关问题