【问题标题】:Persistent bottom sheet form data持久底部表单数据
【发布时间】:2020-03-07 16:53:49
【问题描述】:

我在底页上有一张表格。单击一个按钮即可打开它。当用户在表单外点击时,它可以关闭。如果用户重新打开表单,我想维护表单数据。我不想明确分配每个表单字段值。有没有其他方法可以保存表单状态并在再次创建底部工作表时重复使用它?

  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
              ));}
    );

【问题讨论】:

    标签: forms flutter bottom-sheet


    【解决方案1】:

    所以我终于找到了使用 Provider 维护状态的最佳方法之一。我还探索了其他方式,例如 BLOC,但它非常冗长。我们可以将 BLOC 用于其他情况,但 Provider 是在底部工作表的情况下更好的解决方案。

    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);
                },
              )),
            ));
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多