出现软键盘时,状态会重新创建

时间:2019-12-02 14:49:46

标签: flutter dart

我有一个使用FutureBuilder显示信息的应用程序。

当我打开Textfield时,出现软键盘,并重新创建FutureBuilder的状态。有什么方法可以避免不必要地运行build方法。

显然,当我使用init状态调用future时,它可以工作,但对于其他功能(如删除数据),则不起作用,因为future只被调用一次。

这是我的代码

         class FutureBuilderWidget extends StatefulWidget {
          @override
          _FutureBuilderWidgetState createState() => _FutureBuilderWidgetState();
        }

        class _FutureBuilderWidgetState extends State<FutureBuilderWidget> {
          final _appBar = AppBar();

          @override 
          Widget build(BuildContext context) {
            return FutureBuilder(
                      future: Provider.of<QuickNotesProvider>(context, listen: false)
                          .fetchAndSetNotes(),
                      builder: (ctx, snapshot) {
                        return snapshot.connectionState == ConnectionState.waiting
                            ? Center(
                                child: Text('loading...'),
                              )
                            : Consumer<QuickNotesProvider>(
                                child: Center(
                                  child: Container(
                                    margin: EdgeInsets.only(
                                        top: MediaQuery.of(context).size.height * 0.3),
                                    child: Column(
                                      children: <Widget>[
                                        Icon(Icons.calendar_today,
                                            size: MediaQuery.of(context).size.height *
                                                0.07),
                                        SizedBox(
                                          height: 6,
                                        ),
                                        Text('Added Notes will appear here',
                                            style:
                                                Theme.of(context).textTheme.headline),
                                        SizedBox(
                                          height: 10,
                                        ),
                                        Text(
                                          'Tap + to add a quick note',
                                          style: TextStyle(
                                              fontSize:
                                                  MediaQuery.of(context).size.height *
                                                      0.02,
                                              fontWeight: FontWeight.w400),
                                        )
                                      ],
                                    ),
                                  ),
                                ),
                                builder: (ctx, eventData, ch) {
                                  if (eventData.quicknotes.length == 0) {
                                    return ch;
                                  } else {
                                    return Container(
                                      height: (MediaQuery.of(context).size.height -
                                              _appBar.preferredSize.height -
                                              MediaQuery.of(context).padding.top -
                                              MediaQuery.of(context).padding.bottom) *
                                          0.869,
                                      child: ListView.builder(
                                        itemCount: eventData.quicknotes.length,
                                        itemBuilder: (context, index) {
                                          return Container(
                                              margin: const EdgeInsets.only(
                                                  left: 10, top: 7, right: 10),
                                              child: Card(
                                                elevation: 5,
                                                shape: RoundedRectangleBorder(
                                                    borderRadius:
                                                        BorderRadius.circular(5)),
                                                color: Color.fromRGBO(230, 230, 230, 1),
                                                child: Column(
                                                  crossAxisAlignment:
                                                      CrossAxisAlignment.start,
                                                  children: <Widget>[
                                                    Padding(
                                                      padding: EdgeInsets.only(
                                                          top: 10, left: 8),
                                                      child: Text(
                                                        eventData.quicknotes[index]
                                                            .quicknote,
                                                      ),
                                                    ),
                                                    Row(
                                                      mainAxisAlignment:
                                                          MainAxisAlignment.end,
                                                      children: <Widget>[
                                                        Padding(
                                                          padding:
                                                              const EdgeInsets.only(
                                                                  right: 10.0),
                                                          child: InkWell(
                                                            onTap: () {
                                                              setState(() {
                                                                eventData.deleteEvents(
                                                                    eventData
                                                                        .quicknotes[
                                                                            index]
                                                                        .id);
                                                              });
                                                            },
                                                            child: Icon(
                                                              Icons.more_horiz,
                                                              color: Colors.black54,
                                                            ),
                                                          ),
                                                        )
                                                      ],
                                                    )
                                                  ],
                                                ),
                                              ));
                                        },
                                      ),
                                    );
                                  }
                                });
                      },
                    );
          }
        }

1 个答案:

答案 0 :(得分:0)

那是正常的。当软键盘出现时,您的布局便会调整大小,因此会重新构建。

您可以通过在小部件的resizeToAvoidBottomInsets祖先中设置Scaffold来避免调整大小,但是如果发生任何重建,问题将自行解决。

一种解决方法是将Future结果缓存。 我相信您可以使用Completer来阻止重新执行。

在您的State中创建

var myCompleter = Completer<YourDataDype>()

然后在initState中启动您的future函数,但不要返回结果,而是这样做:

myCompleter.complete(yourData)

然后您可以将myCompleter.future传递到FutureBuilder并查看会发生什么情况。

就我个人而言,我从来没有做过此事,因为我使用BLoC pattern将逻辑和演示分开了,但是它确实适合您的情况。

您也应该开始拆分逻辑,因为这将避免很多麻烦并提高代码库质量!