Flutter:未处理的异常:“Mood”类型不是“MoodType”类型的子类型

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

我是一名尝试创建心理健康应用程序的初级程序员。在日历屏幕中,您可以按一个日期,然后您将被转发到日记条目屏幕,您可以在其中选择

DropdownButtonFormField
的心情并在
TextFormField
中写日记条目。当我选择一种心情时,我得到一个错误
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Mood' is not a subtype of type 'MoodType'
。问题是什么,我该如何解决?

这是完整的错误日志: 在 801 毫秒后重新启动应用程序。 I/zygote (15437): 做部分代码缓存收集,代码=61KB,数据=53KB I/zygote (15437): 代码缓存收集后,代码=61KB,数据=53KB I/zygote (15437):将代码缓存容量增加到 256KB I/flutter (15437): 选择日期:2023-05-03 00:00:00.000 E/flutter (15437): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] 未处理的异常:类型 'Mood' 不是类型 'MoodType' 的子类型 E/颤振 (15437): #0 _JournalEntryScreenState.build.. (package:v1/journal_entry.dart:137:21) E/flutter (15437): #1 State.setState (包:flutter/src/widgets/framework.dart:1133:30) E/flutter (15437):#2 _JournalEntryScreenState.build。 (包:v1/journal_entry.dart:136:19) E/flutter (15437): #3 _DropdownButtonFormFieldState.didChange (包:flutter/src/material/dropdown.dart:1686:39) E/flutter (15437):#4 _DropdownButtonState._handleTap。 (包:flutter/src/material/dropdown.dart:1325:25) E/颤动(15437): E/颤动(15437):


**journal_entry.dart:**
import 'package:flutter/material.dart';
import 'db_helper.dart';
import 'event_interface.dart';
import 'package:intl/intl.dart';
import 'mood_type.dart';
class JournalEntry extends StatefulWidget implements EventInterface {

  final int id;
  @required final DateTime date;
  final MoodType mood;
  final String entry;

  JournalEntry({this.id, @required this.date, @required this.mood, this.entry});

  @override
  DateTime get eventDate => date;

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'date': date?.millisecondsSinceEpoch ?? 0,
      'mood': mood?.index ?? 0,
      'entry': entry,
    };
  }

  static JournalEntry fromMap(Map<String, dynamic> map) {
    return JournalEntry(
      id: map['id'],
      date: DateTime.fromMillisecondsSinceEpoch(map['date']),
      mood: MoodType.values[map['mood']],
      entry: map['entry'],
    );
  }
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
          other is JournalEntry &&
              runtimeType == other.runtimeType &&
              id == other.id &&
              date == other.date &&
              mood == other.mood &&
              entry == other.entry;

  @override
  int get hashCode =>
      id.hashCode ^ date.hashCode ^ mood.hashCode ^ entry.hashCode;

  @override
  _JournalEntryState createState() => _JournalEntryState();
}

class _JournalEntryState extends State<JournalEntry> {

  @override
  Widget build(BuildContext context) {
    throw UnimplementedError();
  }
}

class JournalEntryScreen extends StatefulWidget {

  final DateTime selectedDate;

  JournalEntryScreen({Key key, this.selectedDate}) : super(key: key);

  @override
  _JournalEntryScreenState createState() => _JournalEntryScreenState();
}

class _JournalEntryScreenState extends State<JournalEntryScreen> {
  DateTime _selectedDate;
  final _formKey = GlobalKey<FormState>();
  TextEditingController _journalEntryController = TextEditingController();
  String _journalEntry = '';
  MoodType _selectedMood;

  @override
  void initState() {
    super.initState();
    _selectedDate = widget.selectedDate ?? DateTime.now();
    _getJournalEntry(_selectedDate);
  }

  void _getJournalEntry(DateTime date) async {
    DatabaseHelper databaseHelper = DatabaseHelper.instance;

    List<JournalEntry> entries =
    await databaseHelper.getJournalEntryByDate(date);
    if (entries != null && entries.isNotEmpty) {
      JournalEntry entry = entries.first;
      print('Retrieved journal entry for date: ${entry.date}');
      setState(() {
        _journalEntry = entry.entry;
        _selectedDate = entry.date;
        _selectedMood = entry.mood;
        print('Selected date updated to: $_selectedDate');
      });
      print('Set state for date: $_selectedDate and journal entry: $_journalEntry');
      _journalEntryController.text = _journalEntry;
    }
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text('Journal Entry'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                DateFormat.yMMMMd().format(widget.selectedDate ?? DateTime.now()),
                style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
              ),
              SizedBox(height: 16.0),
              DropdownButtonFormField(
                value: _selectedMood,
                hint: Text('Select a mood'),
                items: moodMap.values
                    .map((mood) => DropdownMenuItem(
                  value: mood,
                  child: Text(mood.name),
                ))
                    .toList(),
                onChanged: (value) {
                  setState(() {
                    _selectedMood = value;
                  });
                },
                validator: (value) {
                  if (value == null) {
                    return 'Please select a mood';
                  }
                  return null;
                },
              ),
              TextFormField(
                controller: _journalEntryController,
                decoration: InputDecoration(
                  hintText: 'Write your journal entry here',
                  border: OutlineInputBorder(),
                ),
                maxLines: null,
                onChanged: (value) {
                  setState(() {
                    _journalEntry = value;
                  });
                },
                validator: (value) {
                  if (value.isEmpty) {
                    return 'Please enter some text';
                  }
                  return null;
                },
              ),
              SizedBox(height: 16.0),
              ElevatedButton(
                onPressed: () async {
                  if (_formKey.currentState.validate()) {
                    JournalEntry entry = JournalEntry(
                      date: widget.selectedDate,
                      mood: _selectedMood,
                      entry: _journalEntry,
                    );
                    DatabaseHelper databaseHelper = DatabaseHelper.instance;
                    int id = await databaseHelper.insertJournalEntry(entry);
                    Navigator.pop(context, true);
                  }
                },
                child: Text('Save'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

**mood_type.dart:**
import 'dart:ui';
import 'package:flutter/material.dart';

enum MoodType {
  veryHappy,
  happy,
  neutral,
  sad,
  verySad
}

class Mood {
  final String name;
  final Color color;
  final MoodType type;

  Mood({this.name, this.color, this.type});
}

final moodMap = {
  MoodType.veryHappy: Mood(name: 'Very Happy', color: Colors.green, type: MoodType.veryHappy),
  MoodType.happy: Mood(name: 'Happy', color: Colors.lightGreen, type: MoodType.happy),
  MoodType.neutral: Mood(name: 'Neutral', color: Colors.grey, type: MoodType.neutral),
  MoodType.sad: Mood(name: 'Sad', color: Colors.blue, type: MoodType.sad),
  MoodType.verySad: Mood(name: 'Very Sad', color: Colors.black87, type: MoodType.verySad),
};

如果需要重现错误,我还可以添加 calendar_screen.dart 和 db_helper.dart。

我尝试重构代码以使用 MoodType 类型而不是心情,并尝试将 MoodType 实现到 Mood 类,但我觉得完全卡住了。

flutter dart unhandled-exception
2个回答
0
投票

您的下拉列表基于

Mood
,但您的
_selectedMood
MoodType
。在 onchanged 中,您尝试将
Mood
分配给
MoodType
。尝试改变

            onChanged: (value) {
              setState(() {
                _selectedMood = value;
              });
            },

            onChanged: (value) {
              setState(() {
                _selectedMood = value.type;
              });
            },

我相信在物品上也犯了类似的错误。我觉得

            items: moodMap.values
                .map((mood) => DropdownMenuItem(
              value: mood,
              child: Text(mood.name),
            ))

需要

            items: moodMap.values
                .map((mood) => DropdownMenuItem(
              value: mood.type,
              child: Text(mood.name),
            ))

0
投票

你的

_selectedMood
对象是一个
MoodType
,所以你的
DropdownMenuItem
s值(当前来自
Mood
的整个
moodMap
对象)应该是相同的类型。

像这样改变他们的

value
属性应该可以解决问题:

DropdownButtonFormField(
                value: _selectedMood,
                hint: Text('Select a mood'),
                items: moodMap.values
                    .map((mood) => DropdownMenuItem(
                  value: mood.type,
                  child: Text(mood.name),
                ))
                    .toList(),
                ...

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