在不按下按钮的情况下触发 floatingActionButton onPressed

Trigger floatingActionButton onPressed without pressing the button

我是 Flutter 的新手,我正在制作一个待办事项应用程序。当我单击属于另一个小部件的 ElevatedButton 时,我希望能够打开一个 showModalBottomSheet 小部件。理想情况下,当用户单击属于 ToDo 小部件之一的“编辑”时,它会打开。

最坏的情况下,我可能会使用另一个 showModalBottomSheet 进行编辑操作,但我希望能够重复使用我现有的 showModalBottomSheet 进行编辑以及新的待办事项,因为它已经在地方。我需要做的就是在用户选择“编辑”时触发它重新打开。

这是我在 MyApp 中的代码。如果需要,我可以包含 NewToDo 的代码,但我觉得该代码不是问题所在。

import 'package:flutter/material.dart';
import './todoitem.dart';
import './todolist.dart';
import 'classes/todo.dart';
import './newtodo.dart';


void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'To Do Homie',
      theme: ThemeData(
        primarySwatch: Colors.deepPurple,
      ),
      home: const MyHomePage(title: "It's To Do's My Guy"),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    Key? key, 
    required this.title,
  }) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String content = '';
  String title = '';
  int maxId = 0;
  ToDo? _todo;
  final titleController = TextEditingController();
  final contentController = TextEditingController();
  List<ToDo> _todos = [];

  void _addTodo(){

    final todo = ToDo ( 
      title: title,
      id: maxId,  
      isDone: false,
      content: content
    );

    if (_todo != null){
      setState(() {
        _todos[_todos.indexOf(_todo!)] = todo;
      });
    } else {
      setState(() {
        _todos.add(todo);
      });
    }

    setState(() {
      content = '';
      maxId = maxId++;
      title = '';
      _todo = null;
    });

    contentController.text = '';
    titleController.text = '';
    
  }

  @override
  void initState() {
    super.initState();
    titleController.addListener(_handleTitleChange);
    contentController.addListener(_handleContentChange);
  }

  void _handleTitleChange() {
    setState(() {
      title = titleController.text;
    });
  }

  void _handleContentChange() {
    setState(() {
      content = contentController.text;
    });
  }

  void _editTodo(ToDo todoitem){
    setState(() {
      _todo = todoitem;
      content = todoitem.content;
      title = todoitem.title;
    });
    contentController.text = todoitem.content;
    titleController.text = todoitem.title;
  }

  void _deleteToDo(ToDo todoitem){
    setState(() {
      _todos = List.from(_todos)..removeAt(_todos.indexOf(todoitem));
    });
  }

  void _clear(){
    contentController.text = '';
    titleController.text = '';
    setState(() {
      content = '';
      title = '';
      _todo = null;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SingleChildScrollView( 
        child: Center(
          child: Container(
            alignment: Alignment.topCenter,
            child: ToDoList(_todos, _editTodo, _deleteToDo)
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          showModalBottomSheet<void>(
            context: context,
            builder: (BuildContext context) {
              return ValueListenableBuilder(
                valueListenable: titleController,
                builder: (context, _content, child) {
                  return NewToDo(titleController, contentController, _addTodo, _clear, _todo);
                });
              });
        },
        child: const Icon(Icons.add),
        backgroundColor: Colors.deepPurple,
      ),
    );
  }
}

尝试在它自己的方法中提取 showModalBottomSheet 并将其传递给 onPressed,如下所示:

floatingActionButton: FloatingActionButton(
        onPressed: _triggerBottomSheet,


// then create the method
void _triggerBottomSheet(){
showModalBottomSheet<void>(
            context: context,
            builder: (BuildContext context) {
              return ValueListenableBuilder(
                valueListenable: titleController,
                builder: (context, _content, child) {
                  return NewToDo(titleController, contentController, _addTodo, _clear, _todo);
                });
              });