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

Flutter跨页面传值并保存到ListView问题求助

Hey there, let's break down and fix your issues one by one. I've gone through your code and spotted several key problems causing the unexpected behavior:


1. Why clicking save does nothing & content is empty in console

The core issue here is that your data.content only gets updated when you trigger onFieldSubmitted (like pressing Enter in the TextField). When you directly tap the save icon, this callback never runs—so data.content stays empty, failing your if (data.content != '') check, hence no action happens.

Fix:

Update your AddingTextField to sync content to Data in real-time as the user types, and ensure the save button navigates back to the home page after saving:

class _AddingTextFieldState extends State<AddingTextField> {
  TextEditingController _textEditingController;

  @override
  void initState() {
    _textEditingController = TextEditingController(text: widget.text);
    // Sync initial edit content to Data if provided
    if (widget.text != null) {
      context.read<Data>().addContent(widget.text);
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var data = context.read<Data>();
    return Padding(
      padding: const EdgeInsets.all(15),
      child: TextFormField(
        controller: _textEditingController,
        maxLines: widget.maxLines,
        decoration: InputDecoration(hintText: widget.hintText),
        // Update Data.content whenever text changes
        onChanged: (value) {
          data.addContent(value);
        },
      ),
    );
  }
}

Then fix the save button action in AddNoteScreen:

CustomAppBar(
  title: 'Add Note',
  icon: Icons.save,
  onPressed: () {
    print(data.content);
    if (data.content.isNotEmpty) {
      data.addNote();
      Navigator.pop(context); // Critical: return home to refresh ListView
    }
  },
),

2. Data not showing up in home ListView

Your Data class has inconsistencies in data handling and persistence:

  • You commented out all title logic but still include titles in file operations, leading to corrupted data
  • String-splitting for file I/O is error-prone (breaks if notes contain |/,/[])
  • Redundant code like content=content; in addNote

Fix the Data class (overhauled for reliability):

class Data extends ChangeNotifier {
  String content = '';
  int? editingIndex; // Track if we're editing an existing note
  List<Map<String, String>> notes = []; // Better structure: list of note objects

  void addContent(String value) {
    content = value;
    print('Updated content: $content');
    notifyListeners();
  }

  /// Add new note or update existing one
  void saveNote() {
    if (content.isEmpty) return;
    
    final now = DateTime.now();
    final currentTime = '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}';

    if (editingIndex != null) {
      // Update existing note
      notes[editingIndex!] = {'content': content, 'time': currentTime};
      editingIndex = null;
    } else {
      // Add new note
      notes.add({'content': content, 'time': currentTime});
    }
    
    content = '';
    notifyListeners();
    writeFile();
  }

  void removeNote(int index) {
    notes.removeAt(index);
    notifyListeners();
    writeFile();
  }

  // Prepare for editing a note
  void editNote(int index) {
    content = notes[index]['content']!;
    editingIndex = index;
    notifyListeners();
  }

  Future<String> appPath() async {
    final document = await getApplicationDocumentsDirectory();
    return document.path;
  }

  Future<File> appFile() async {
    final path = await appPath();
    return File('$path/notes.json');
  }

  // Use JSON for reliable serialization
  Future writeFile() async {
    final file = await appFile();
    return file.writeAsString(jsonEncode(notes));
  }

  Future readFile() async {
    try {
      final file = await appFile();
      if (!await file.exists()) {
        notes = [];
        return;
      }
      final jsonString = await file.readAsString();
      final List<dynamic> decoded = jsonDecode(jsonString);
      notes = decoded.map((item) => Map<String, String>.from(item)).toList();
      notifyListeners();
    } catch (e) {
      print('Error loading notes: $e');
      notes = [];
    }
  }
}

Update AddNoteScreen to support edit mode:

class AddNoteScreen extends StatelessWidget {
  final String? editContent;
  final int? editIndex;

  AddNoteScreen({this.editContent, this.editIndex});

  @override
  Widget build(BuildContext context) {
    var data = context.watch<Data>();

    // Initialize edit state if needed
    if (editIndex != null && editContent != null) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        data.editNote(editIndex!);
      });
    }

    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            CustomAppBar(
              title: editIndex != null ? 'Edit Note' : 'Add Note',
              icon: Icons.save,
              onPressed: () {
                if (data.content.isNotEmpty) {
                  data.saveNote();
                  Navigator.pop(context);
                }
              },
            ),
            Flexible(
              child: AddingTextField(
                maxLines: 500,
                text: editContent ?? '',
                hintText: 'Write your note...',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

3. Clicking ListTile doesn't open edit page

In your home page's ListView.builder, pass the note's content and index to AddNoteScreen when tapping a ListTile:

ListView.builder(
  itemCount: data.notes.length,
  itemBuilder: (context, index) {
    final note = data.notes[index];
    return ListTile(
      title: Text(note['content']!.substring(0, 20) + '...'),
      subtitle: Text(note['time']!),
      onTap: () {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => AddNoteScreen(
              editContent: note['content'],
              editIndex: index,
            ),
          ),
        );
      },
      trailing: IconButton(
        icon: Icon(Icons.delete),
        onPressed: () => data.removeNote(index),
      ),
    );
  },
)

Final Quick Checks

  • Ensure you've wrapped your app with ChangeNotifierProvider for Data in main.dart
  • Call data.readFile() when your app starts (e.g., in main.dart after initializing the provider) to load saved notes

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:42:56