Trigger floatingActionButton onPressed without pressing the button

837

Try extracting the showModalBottomSheet in its own method and pass it to the onPressed like this:

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);
                });
              });
Share:
837
Matt Croak
Author by

Matt Croak

Updated on January 01, 2023

Comments

  • Matt Croak
    Matt Croak over 1 year

    I'm new to Flutter and I'm making a To Do app. I want to be able to open a showModalBottomSheet widget when I click an ElevatedButton that belongs to another widget. Ideally it would open when the user clicks "Edit" belonging to one of the ToDo widgets.

    enter image description here

    Worst case I could probably use another showModalBottomSheet for the edit action but I'd love to be able to reuse my existing showModalBottomSheet for edits as well as new to do's since it's already in place. All I need to do is trigger it to reopen when the user selects "Edit".

    Here is my code in MyApp. I can include code for NewToDo if requested but I feel like that code isn't the issue.

    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,
          ),
        );
      }
    }
    
    • eimmer
      eimmer over 2 years
      Why don't you extract the contents of the onPressed for the FAB into it's own method, and call that from the edit button?
    • Matt Croak
      Matt Croak over 2 years
      @eimmer ... * face palm * thanks so much!