首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >颤振:如何在打开键盘时防止多个MaterialApp.router构建器调用?

颤振:如何在打开键盘时防止多个MaterialApp.router构建器调用?
EN

Stack Overflow用户
提问于 2022-09-12 19:29:04
回答 1查看 89关注 0票数 1

我找不到答案来回答我的问题,基本上所有类似的情况都与重建使用MediaQuery的小部件有关(但在我的例子中并非如此)。当我点击TextField时,键盘就会出现,在此之后,MaterialApp.router中的构建器会被调用数十次。有可能避免这么多的建筑商调用吗?

main.dart:

代码语言:javascript
复制
import 'package:flutter/material.dart';
import 'package:routemaster/routemaster.dart';

final routes = RouteMap(
  onUnknownRoute: (route) => const Redirect("/"),
  routes: {
    '/': (_) => const MaterialPage(child: FirstPage()),
  },
);

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      builder: (context, widget) {
        debugPrint("Info: MaterialApp.router Build");
        return widget!;
      },
      routeInformationParser: const RoutemasterParser(),
      routerDelegate: RoutemasterDelegate(
        routesBuilder: (context) {
          debugPrint("Info: Router Build");
          return routes;
        },
      ),
    );
  }
}

class FirstPage extends StatelessWidget {
  const FirstPage({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    debugPrint("Info: FirstPage Build");
    return Scaffold(
      body: Column(
        children: const [
          Padding(
            padding: EdgeInsets.only(top: 200),
            child: TextField(),
          ),
        ],
      ),
    );
  }
}

控制台:

代码语言:javascript
复制
Launching lib/main.dart on iPhone 13-2 in debug mode...
Running Xcode build...
Xcode build done.                                           14,4s
Debug service listening on ws://127.0.0.1:62493/BzKbBCNai2Q=/ws
Syncing files to device iPhone 13-2...
flutter: Info: MaterialApp.router Build
flutter: Info: Router Build
flutter: Info: FirstPage Build
flutter: Info: MaterialApp.router Build // opening keyboard
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
flutter: Info: MaterialApp.router Build
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-12 19:56:20

对你的问题的简短回答是“有点”。https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html为优化构建方法以减少性能影响提供了几个建议,其中包括减少调用数量的方法:

尽量减少由构建方法和它创建的任何小部件临时创建的节点数。例如,不需要精心安排行、列、填充和SizedBoxes来以一种特别奇特的方式定位单个子节点,而是考虑只使用对齐或CustomSingleChildLayout。考虑单个CustomPaint小部件,而不是复杂的多容器分层和带有装饰来绘制正确的图形效果。

在可能的情况下使用const小部件,并为小部件提供一个const构造函数,以便小部件的用户也可以这样做。

考虑将无状态小部件重构为有状态小部件,以便它可以使用StatefulWidget中描述的一些技术,例如缓存子树的公共部分和在更改树结构时使用GlobalKeys。

如果由于使用InheritedWidgets而可能频繁地重建小部件,请考虑将无状态小部件重构为多个小部件,将更改的树的部分推到叶子上。例如,不要构建一个包含四个小部件的树,而构建最内部的小部件取决于主题,考虑将构建函数中构建最内部小部件的部分分解到自己的小部件中,以便在主题发生变化时只需要重建最内部的小部件。

当尝试创建可重用的UI时,更喜欢使用小部件而不是助手方法。例如,如果有一个用于构建小部件的函数,则需要State.setState调用才能完全重建返回的包装小部件。如果使用Widget,则Flutter将能够高效地重新呈现那些真正需要更新的部分。更好的是,如果创建的小部件是const,则Flutter将中断大部分重建工作。

每次build方法发生更改时都会调用该方法:

当这个小部件被插入到给定的

中的树中时,以及当这个小部件的依赖项发生变化时,框架调用这个方法(例如,这个小部件引用的一个InheritedWidget发生了变化)。这个方法可以在每个框架中调用,并且除了构建一个小部件之外,不应该有任何副作用。(来自https://api.flutter.dev/flutter/widgets/Builder/build.html.)

基于上面的两个链接,最好的方法可能是使FirstPage()成为一个有状态的小部件,这样它就可以更好地适应键盘的打开。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73694371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档