You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现选中问题添加至指定自定义列表的技术求助

解决方案

核心问题在于你的CreatedList模型未关联问题集合,且CreatedListsNotifier缺少将问题与指定列表绑定的逻辑。以下是完整修正步骤:

1. 重构CreatedList数据结构

确保每个列表包含自身标题和对应的问题集合,并重写比较方法保证列表能被正确识别:

class CreatedList {
  final String title;
  final List<Question> questions;

  CreatedList({required this.title, List<Question>? questions})
      : questions = questions ?? [];

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is CreatedList &&
          runtimeType == other.runtimeType &&
          title == other.title;

  @override
  int get hashCode => title.hashCode;

  // 用于复制列表并更新问题集合
  CreatedList copyWith({List<Question>? questions}) {
    return CreatedList(
      title: title,
      questions: questions ?? this.questions,
    );
  }
}

2. 更新CreatedListsNotifier逻辑

添加管理问题与列表关联的核心方法,保留原有列表增删逻辑:

class CreatedListsNotifier extends StateNotifier<List<CreatedList>> {
  CreatedListsNotifier() : super([]);

  // 创建新列表并直接添加当前问题
  void createListWithQuestion(CreatedList newList, Question question) {
    if (!state.contains(newList)) {
      final updatedList = newList.copyWith(questions: [question]);
      state = [...state, updatedList];
    }
  }

  // 给已有列表添加/移除指定问题
  void toggleQuestionInList(CreatedList targetList, Question question) {
    state = state.map((list) {
      if (list == targetList) {
        final updatedQuestions = List.of(list.questions);
        updatedQuestions.contains(question) 
            ? updatedQuestions.remove(question) 
            : updatedQuestions.add(question);
        return list.copyWith(questions: updatedQuestions);
      }
      return list;
    }).toList();
  }

  // 从所有列表中移除某个问题
  void removeQuestionFromAllLists(Question question) {
    state = state.map((list) {
      final updatedQuestions = List.of(list.questions)..remove(question);
      return list.copyWith(questions: updatedQuestions);
    }).toList();
  }

  // 原有列表创建/删除方法
  bool toggleCreatedListsStatus(CreatedList newestList) {
    final alreadyCreatedList = state.contains(newestList);
    if (alreadyCreatedList) {
      state = state.where((L) => L.title != newestList.title).toList();
      return false;
    } else {
      state = [...state, newestList];
      return true;
    }
  }

  void onDismissListItem(CreatedList item) {
    state = state.where((indexeditem) => indexeditem.title != item.title).toList();
  }
}

final createdListsProvider = StateNotifierProvider<CreatedListsNotifier, List<CreatedList>>((ref) {
  return CreatedListsNotifier();
});

3. 重构favoriteQuestionsProvider

让它自动计算所有列表中的问题集合,无需单独维护:

final favoriteQuestionsProvider = Provider<List<Question>>((ref) {
  final createdLists = ref.watch(createdListsProvider);
  // 合并所有列表的问题并去重
  return createdLists.expand((list) => list.questions).toSet().toList();
});

4. 修改主页面逻辑

传递当前问题到弹窗,并处理移除所有列表的逻辑:

@override
Widget build(BuildContext context) {
  List<Question> getNewListofQuestions = List.of(widget.questions);
  getNewListofQuestions.shuffle();
  var currentQuestion = getNewListofQuestions[currentQuestionIndex];

  final favoriteQuestions = ref.watch(favoriteQuestionsProvider);
  final isFavorite = favoriteQuestions.contains(currentQuestion);

  void openAddNewListOverlay() {
    if (isFavorite) {
      ref.read(createdListsProvider.notifier).removeQuestionFromAllLists(currentQuestion);
      ScaffoldMessenger.of(context).clearSnackBars();
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          duration: Duration(seconds: 1),
          content: Text('Question removed from all your lists.'),
        ),
      );
    } else {
      showModalBottomSheet(
        shape: const BeveledRectangleBorder(
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10),
            topRight: Radius.circular(10),
          ),
        ),
        isScrollControlled: true,
        useSafeArea: true,
        context: context,
        builder: (ctx) => QuestionsOverlayItem(
          currentQuestion: currentQuestion,
          onCreateList: (newList) {
            ref.read(createdListsProvider.notifier).createListWithQuestion(newList, currentQuestion);
          },
          onSelectExistingList: (existingList) {
            ref.read(createdListsProvider.notifier).toggleQuestionInList(existingList, currentQuestion);
          },
        ),
      );
    }
  }

  // 剩余UI代码保持不变...
}

5. 调整弹窗组件QuestionsOverlayItem

添加已有列表的展示和选择逻辑(需改为ConsumerWidget或使用Consumer获取Provider):

class QuestionsOverlayItem extends ConsumerWidget {
  final Question currentQuestion;
  final Function(CreatedList)? onCreateList;
  final Function(CreatedList)? onSelectExistingList;

  const QuestionsOverlayItem({
    super.key,
    required this.currentQuestion,
    this.onCreateList,
    this.onSelectExistingList,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final createdLists = ref.watch(createdListsProvider);

    return Padding(
      padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // 新建列表输入框
          TextField(
            decoration: const InputDecoration(labelText: 'New List Title'),
            onSubmitted: (title) {
              if (title.isNotEmpty) {
                onCreateList?.call(CreatedList(title: title));
                Navigator.pop(context);
              }
            },
          ),
          const SizedBox(height: 16),
          // 已有列表选择区
          const Text('Add to existing lists:'),
          ...createdLists.map((list) {
            return ListTile(
              title: Text(list.title),
              trailing: Icon(
                list.questions.contains(currentQuestion) ? Icons.check : null,
              ),
              onTap: () {
                onSelectExistingList?.call(list);
                Navigator.pop(context);
              },
            );
          }),
        ],
      ),
    );
  }
}

完成以上修改后,即可实现:

  • 点击星标,若问题已在列表中则从所有列表移除
  • 弹窗中可新建列表并添加当前问题,或选择已有列表添加/移除问题
  • favoriteQuestionsProvider自动同步所有列表中的问题

内容的提问来源于stack exchange,提问作者yosoybunal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 03:03:12