Flutter PopupMenuButton 带有动态项目动画错误

问题描述 投票:0回答:1

我尝试创建一个带有动态项目列表的 PopupMenuButton,如下所示:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wideview/view_models/task_control_view_model.dart';
import 'package:wideview/widgets/gap.dart';

class TaskPopupMenuView extends ConsumerWidget {
  const TaskPopupMenuView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final taskControlViewModel = ref.watch(taskControlViewModelProvider);
    List<Task>? tasks = taskControlViewModel.tasks;

    return PopupMenuButton<Task>(
      offset: const Offset(120, 50),
      // constraints: const BoxConstraints(
      //   maxHeight: 500,
      // ),
      icon: const TaskIcon(),
      onSelected: (item) => {
        if (item.isSelected)
          {
            ref.read(taskControlViewModelProvider.notifier).setNoSelectedTask(),
          }
        else
          {
            ref
                .read(taskControlViewModelProvider.notifier)
                .setSelectedTask(item),
          }
      },
      itemBuilder: (context) {
        // Build the list of PopupMenuItem dynamically based on tasks
        return tasks?.map((Task task) {
              return PopupMenuItem<Task>(
                value: task,
                child: TaskPopupView(task: task),
              );
            }).toList() ??
            [];
      },
      // itemBuilder: (context) => [
      //   PopupMenuItem<Task>(
      //       value: taskControlViewModel.selectedTask,
      //       child: TaskPopupView(task: taskControlViewModel.selectedTask!)),
      //   PopupMenuItem<Task>(
      //       value: taskControlViewModel.selectedTask,
      //       child: TaskPopupView(task: taskControlViewModel.selectedTask!)),
      //   PopupMenuItem<Task>(
      //       value: taskControlViewModel.selectedTask,
      //       child: TaskPopupView(task: taskControlViewModel.selectedTask!)),
      // ],
    );
  }
}

列表中的每个项目都会显示一个文本,该文本随弹出菜单的打开/关闭动画一起显示。 问题是这个列表很长,因此,为了限制其长度,我添加了注释字段:

// constraints: const BoxConstraints(
//   maxHeight: 500,
// ),

这解决了长度问题,但现在当我打开/关闭菜单时,该项目的动画与菜单不同步,文本只是出现并立即消失。 这是为什么?我该如何解决它?

注意:当使用非动态项目列表时,如下所示:

      // itemBuilder: (context) => [
      //   PopupMenuItem<Task>(
      //       value: taskControlViewModel.selectedTask,
      //       child: TaskPopupView(task: taskControlViewModel.selectedTask!)),
      //   PopupMenuItem<Task>(
      //       value: taskControlViewModel.selectedTask,
      //       child: TaskPopupView(task: taskControlViewModel.selectedTask!)),
      //   PopupMenuItem<Task>(
      //       value: taskControlViewModel.selectedTask,
      //       child: TaskPopupView(task: taskControlViewModel.selectedTask!)),
      // ],

这个动画错误不会出现,并且工作正常。

  • 我尝试创建自定义 PopupMenuButton,最终遇到了相同的错误。

  • 我尝试为列表中的每个项目提供自己的动画(适用于打开菜单,但不适用于关闭菜单)。

  • 我尝试用 ContrainedBox 小部件包装 PopUpMenuButton,如下所示:

ConstrainedBox(
      constraints: const BoxConstraints(
        maxHeight: 500,
      ),
      child: PopupMenuButton<Task>(

没用。

flutter dart flutter-animation
1个回答
0
投票

我发现您与动态项目的出现/消失不同步。您必须在 PopupMenuButton 中使用 ListViewListView.builder 检查下面的代码:

return PopupMenuButton<Task>(
  offset: const Offset(120, 50),
  icon: const TaskIcon(),
  onSelected: (item) => {
    if (item.isSelected)
      {
        ref.read(taskControlViewModelProvider.notifier).setNoSelectedTask(),
      }
    else
      {
        ref
            .read(taskControlViewModelProvider.notifier)
            .setSelectedTask(item),
      }
  },
  itemBuilder: (context) {
    // Use ListView.builder to build the list of PopupMenuItem dynamically
    return ListView.builder(
      itemCount: tasks?.length ?? 0,
      itemBuilder: (context, index) {
        final task = tasks![index];
        return PopupMenuItem<Task>(
          value: task,
          child: TaskPopupView(task: task),
        );
      },
    );
  },
);

当您使用 ListView.builder 时,您可以创建一个动态项目列表,如果超过指定高度(在您的情况下为 500),该列表将滚动,同时保持动画与 PopupMenuButton 的打开和同步关闭。您可以根据需要调整maxHeight

© www.soinside.com 2019 - 2024. All rights reserved.