Persistent bottom sheet form data

我与影子孤独终老i 提交于 2020-06-17 14:13:15

问题


I have one form on a bottom sheet. It's opened on click of one button. It can be closed when the user clicks outside the form. I want to maintain the form data if the user reopens the form. I don't want to assign each form field value explicitly. Is there any other way of saving the form state and reusing it while creating the bottom sheet again?

  void _modalBottomSheetMenu(BuildContext context, Widget form) async {
    await showModalBottomSheet<dynamic>(
        isDismissible: false,
        isScrollControlled:true,
        context: context,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)),
        ),
        backgroundColor: Colors.white,
        builder: (BuildContext bc) {
          return SingleChildScrollView(
              child: Container(
                  padding:
                  EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
                  child: Padding(
                      padding: const EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 0.0),
                      child: form) // From with TextField inside
              ));}
    );

回答1:


So I finally found one of the best approaches for maintaining the state using Provider. I also explored other ways such as BLOC but it was very verbose for it. We can use BLOC for other cases but Provider is a better solution in case of a bottom sheet.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Bottom Sheet',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChangeNotifierProvider(
        create: (context) => TitleDataNotifier(),
        child: ButtomSheetScreen(),
      ),
    );
  }
}

class TitleDataNotifier with ChangeNotifier {
  String _name;

  String get name => _name;

  set name(String name) {
    _name = name;
    notifyListeners();
  }
}

class AddTaskScreen extends StatefulWidget {
  final TitleDataNotifier valueProvider;

  AddTaskScreen(this.valueProvider);

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

class _AddTaskScreenState extends State<AddTaskScreen> {
  final _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    _controller.text = widget.valueProvider.name;
  }

  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  void deactivate() {
    widget.valueProvider.name = _controller.text;
    super.deactivate();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(20.0),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(20.0),
          topRight: Radius.circular(20.0),
        ),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          Text(
            'Add Task',
            textAlign: TextAlign.center,
            style: TextStyle(
                fontSize: 30.0,
                color: Colors.lightBlueAccent,
                fontWeight: FontWeight.w700),
          ),
          TextField(
            controller: _controller,
            autofocus: false,
            textAlign: TextAlign.center,
            onChanged: (newText) {
              widget.valueProvider._name = newText;
            },
          ),
          FlatButton(
            child: Text(
              'Add',
              style: TextStyle(color: Colors.white),
            ),
            color: Colors.lightBlueAccent,
            onPressed: () {
              Navigator.pop(context);
            },
          )
        ],
      ),
    );
  }
}

class ButtomSheetScreen extends StatelessWidget {
  void openBottomSheet(context) {
    var valueProvider = Provider.of<TitleDataNotifier>(context, listen: false);
    showModalBottomSheet<dynamic>(
      context: context,
      builder: (BuildContext context) {
        return ChangeNotifierProvider.value(
          value: valueProvider,
          child: StatefulBuilder(
              builder: (BuildContext context, StateSetter state) {
            return Padding(
              padding: EdgeInsets.only(
                  bottom: MediaQuery.of(context).viewInsets.bottom),
              child: Wrap(
                children: <Widget>[
                  AddTaskScreen(valueProvider),
                ],
              ),
            );
          }),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(
            "Bottom Sheet",
          ),
        ),
        body: Center(
          child: Container(
              child: IconButton(
            icon: const Icon(Icons.work),
            onPressed: () {
              openBottomSheet(context);
            },
          )),
        ));
  }
}



来源:https://stackoverflow.com/questions/60547602/persistent-bottom-sheet-form-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!