Flutter 2.5 的新特性【Flutter 专题 12】

简介: Flutter 2.5 的新特性2017 年 Flutter 的首次发布标志着跨平台应用程序混合开发新时代的开始。Flutter 风靡全球,在几年内,无数公司和开发人员采用 Flutter 作为开发跨平台应用程序的平台和框架。

Flutter 2.5 的新特性

2017 年 Flutter 的首次发布标志着跨平台应用程序混合开发新时代的开始。Flutter 风靡全球,在几年内,无数公司和开发人员采用 Flutter 作为开发跨平台应用程序的平台和框架。


Flutter 使您能够开发移动(Android 和 iOS)、桌面,甚至在Flutter 2.0发布时,甚至是 Web 应用程序,而无需更改其代码库或从头开始重写应用程序。


这个快速发展的框架的最新版本Flutter 2.5包含了一个全新的、更强大的功能。在本指南中,我们将帮助您熟悉 Flutter 2.5 引入的最值得注意的新功能和改进,包括:


  • 如何升级到 Flutter 2.5
  • 安卓全屏支持
  • Material You (v3) 支持
  • MaterialState.scrolledUnder 并支持 AppBar.backgroundColor
  • 材料 banner
  • 可切换的键盘快捷键
  • 改进的小部件检查器
  • 向 VS Code 项目添加依赖项
  • 新应用模板

如何升级到 Flutter 2.5

您可以通过运行以下命令将 Flutter 版本升级到 v2.5:


flutter upgrade

复制代码


Flutter CLI 工具将完成将您的 Flutter SDK 升级到最新版本 2.5 的工作。


要验证升级是否成功,请运行以下命令:


flutter --version
Flutter 2.5.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 4cc385b4b8 () • 2021-11-27 23:01:49 -0700
Engine • revision f0826da7ef
Tools • Dart 2.14.0



确保 Flutter 版本是2.5.0. 上面的输出是我的系统的结果。

安卓全屏支持

Flutter 对其在 Android 中的全屏模式进行了相当多的更改。全屏模式会影响系统 UI 覆盖的可见性,例如状态和底部导航栏。


这一变化为 Android 和 iOS 引入了新的模式配置,称为倾斜、沉浸式、沉浸式粘性和边缘到边缘。


  • 当在屏幕上的任何位置点击显示时,后仰模式会显示系统 UI 覆盖(状态栏和导航栏)。此操作生成的事件不会传递给应用程序。这种全屏体验类似于 iOS 设备
  • 沉浸模式会导致在边缘滑动屏幕时显示系统 UI 叠加层(状态栏和导航栏)。与后倾模式一样,此操作生成的事件不会传递给应用程序
  • 沉浸式粘性模式类似于沉浸式模式;滑动屏幕边缘时会显示系统 UI 叠加层。这里的区别在于应用程序会收到事件通知
  • 边缘到边缘模式会导致系统 UI 覆盖显示/渲染在应用程序上。应用程序 UI 位于系统(状态栏和导航栏)叠加层的后面

Material You (v3) 支持

Material You是 Material Design 的新 Google 版本。随之而来的是很多支持,Flutter 2.5 支持FloatingActionButton大小和主题。


FloatingActionButton尺寸可被构造成具有四种尺寸:smallregularlarge,和extended

small

FAB 看起来很小。请参阅下面的代码:


floatingActionButton: FloatingActionButton.small(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),



上面的代码将创建并呈现一个小的 FAB 小部件:


image.png


随着方法smalllargeextended被添加到FloatingActionButton类,所以我们可以很容易地通过使用他们,创造各种 FAB 尺寸。

regular

regular尺寸是 FAB 的正常大小。我们可以像平常一样使用它FloatingActionButton


 floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.


large

large 呈现非常大的 FAB 尺寸。


要使用此大小,请调用类中的large方法FloatingActionButton


  floatingActionButton: FloatingActionButton.large(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.


image.png


extended

extended 结合 FAB 上的文本和图标。


extendedFloatingActionButton类上调用该方法。一个label参数被传递给extended方法。此参数将是 FAB 将显示的文本。然后,icon还将一个参数传递给该方法,该icon参数是将显示在 FAB 标签旁边的图标。


 floatingActionButton: FloatingActionButton.extended(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        label: Text("Increment"),
        icon: const Icon(Icons.add),
      )



image.png


我们可以在这个扩展的 FAB 中自定义标签和图标之间的间距。为此,请extendedIconLabelSpacing向该extended方法传递一个参数:


floatingActionButton: FloatingActionButton.extended(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        label: Text("Increment"),
        icon: const Icon(Icons.add),
        extendedIconLabelSpacing: 30
      )


我们将 设置extendedIconLabelSpacing为 的值30


image.png

Flutter 2.5 中的主题浮动操作按钮

我们可以在我们的应用程序中对各种尺寸的 FAB 进行主题化。这是通过FloatingActionButtonThemeData类完成的。


首先,创建一个实例FloatingActionButtonThemeData并将设置传递给它:


const BoxConstraints constraints = BoxConstraints.tightFor(width: 100.0, height: 100.0);
const FloatingActionButtonThemeData(
    largeSizeConstraints: constraints,
    backgroundColor: Colors.green,
),



在上面的示例中,我们将 FAB 的盒模型设置为100.0高度和宽度的单位,并将背景颜色设置为green


让我们将此实例设置FloatingActionButtonThemeData为小部件中的ThemeData调用MaterialApp


@override
  Widget build(BuildContext context) {
    const BoxConstraints constraints = BoxConstraints.tightFor(width: 100.0, height: 100.0);
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        floatingActionButtonTheme: const FloatingActionButtonThemeData(
          largeSizeConstraints: constraints,
          backgroundColor: Colors.green,
        ),
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }


此主题将影响我们将在应用程序中创建的 FAB。我们应用中的所有 FAB 都是100.0宽度和高度单位,背景颜色为绿色。


让我们添加两个 FAB:


floatingActionButton: Container(
    padding: const EdgeInsets.all(50.0),
    child:Row(
    children: [
        FloatingActionButton.extended(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            label: Text("Increment"),
            icon: const Icon(Icons.add),
        ),
        FloatingActionButton.extended(
            onPressed: ()=>{},
            tooltip: 'Decrement',
            label: Text("Decrement"),
            icon: const Icon(Icons.cancel_sharp),
        ),
     ],
    ),
)



我们的两个 FAB 没有设置颜色,但是我们在 中设置的主题ThemeData会影响它们。它们将具有100.0单位和绿色背景的框约束。


image.png

MaterialState.scrolledUnder 并支持 AppBar.backgroundColor

此功能是应用于 AppBar 或 SliverAppBar 的背景颜色的效果。


Flutter 团队的补充一个状态到。当小部件与下方可滚动的内容重叠时,会设置此状态。AppBar 设置此状态以指示一段可滚动内容已向上滚动到其后面。MaterialState.scrolledUnderMaterialState``scrollUnder


通过在 AppBar 或 SliverAppBar 的背景颜色属性中设置监听器,可以在scrollUnder事件触发时更改颜色:


class _MyHomePageState extends State<MyHomePage> {
static Widget buildListItem(BuildContext context, int index) {
    final Color color = Colors.primaries[index % Colors.primaries.length];
    return Padding(
      padding: EdgeInsets.all(2),
      child: ListTile(
        title: Text('List Item $index'),
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backwardsCompatibility: false,
        elevation: 0,
        backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
          return states.contains(MaterialState.scrolledUnder) ? Colors.red : Colors.blue;
        }),
        title: Text('Hello World'),
      ),
      body: ListView.builder(
        itemCount: 200,
        itemBuilder: buildListItem,
      ),
    );
  }
}


我们将 AppBar 设置为backgroundColor从其当前状态解析颜色。我们调用了并在其中设置了一个回调函数。该回调函数接收 AppBa 中的所有状态。MaterialStateColor.resolveWith(...)


然后我们检查状态是否包含. 这告诉我们 AppBar 已被滚动到下方,因此我们返回靛蓝色。如果不是,则返回蓝色。MaterialState.scrolledUnder

image.png


ScrollMetricsNotification

ScrollMetricsNotification功能使您能够侦听滚动条以检测滚动条的内容何时发生更改。如果寡妇或可滚动的父级的大小发生更改,也会通知可滚动。


下面是一个例子:


class _MyHomePageState extends State<MyHomePage> {
  double windowSize = 200.0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backwardsCompatibility: false,
          elevation: 0,
          title: Text('Hello World'),
        ),
        body: NotificationListener<ScrollMetricsNotification>(
          onNotification: (ScrollMetricsNotification notification) {
            ScaffoldMessenger.of(notification.context).showSnackBar(
              const SnackBar(
                content: Text('Scroll metrics changed!'),
              ),
            );
            return false;
          },
          child: Scrollbar(
            isAlwaysShown: true,
            child: SizedBox(
              height: windowSize,
              width: double.infinity,
              child: const SingleChildScrollView(
                child: FlutterLogo(
                  size: 300.0,
                ),
              ),
            ),
          ),
        ),
        floatingActionButton: Container(
          padding: const EdgeInsets.all(50.0),
          child: Row(
            children: [
              FloatingActionButton.extended(
                onPressed: () => {
                  setState(() {
                    windowSize += 10.0;
                  })
                },
                tooltip: 'Adjust WindowSize',
                label: Text("Adjust WindowS"),
                icon: const Icon(Icons.cancel_sharp),
              ),
            ],
          ),
        )
    );
  }
}


image.png


我们有一个Scrollbar封装在NotificationListener小部件中。该ScrollBar有一个SizedBox; 所述SizedBox的高度被附接到windowSize状态。


onNotificationNotificationListener小部件中设置了一个回调。当SizedBox内容更改时调用此回调。请注意,回调接收一个参数,该参数 的实例是ScrollMetricsNotification

MaterialBanner

最后,MaterialBanner类就在这里。此功能使您能够在 Flutter 应用程序的顶部添加 banner。此 banner 会一直保留到被取消为止。


此 Material Design Banner 由ScaffoldMessenger类处理。这个ScaffoldMessenger类有我们可以用来创建和删除 MaterialBanners 的方法。

ScaffoldMessenger.of(context).showMaterialBanner

此方法创建并显示一个 Material Banner。传递一个小部件;这是该方法在我们的应用程序顶部显示的 MaterialBanner。ScaffoldMessenger.of(context).showMaterialBanner``MaterialBanner


ScaffoldMessenger.of(context).showMaterialBanner(
    MaterialBanner(
        content: const Text('Yay!! Do you like me!!'),
        leading: const Icon(Icons.warning),
        backgroundColor: Colors.purple,
        actions: [
            TextButton(
            child: const Text('Dismiss', style: const TextStyle(color: Colors.white)),
            onPressed: () => ScaffoldMessenger.of(context)
                .hideCurrentMaterialBanner(),
            ),
        ],
    ),
)



上面的代码将显示一个 MaterialBanner。看到一个MaterialBanner小部件被传递给showMaterialBanner方法。


MaterialBanner小部件中,我们传递了以下道具:


  • content:这个道具设置 banner 的主体。
  • leading:这将设置在 banner 开头的图标。
  • backgroundColor:这会设置 banner 小部件的背景颜色。
  • actions:这将设置将位于 banner 小部件末尾的按钮。

ScaffoldMessenger.of(context).hideCurrentMaterialBanner

此方法删除现有的 MaterialBanner。


actions: [
    TextButton(
    child: const Text('Dismiss', style: const TextStyle(color: Colors.white)),
    onPressed: () => ScaffoldMessenger.of(context)
        .hideCurrentMaterialBanner(),
    ),
],


完整代码:


// main.dart
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        // Remove the debug banner
        debugShowCheckedModeBanner: false,
        title: '坚果前端',
        theme: ThemeData(
          primarySwatch: Colors.indigo,
        ),
        home: HomePage());
  }
}
class HomePage extends StatefulWidget {
  const HomePage({Key key}) : super(key: key);
  @override
  _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backwardsCompatibility: false,
          elevation: 0,
          title: Text('Hello World'),
        ),
        body: NotificationListener<ScrollMetricsNotification>(
          onNotification: (ScrollMetricsNotification notification) {
            ScaffoldMessenger.of(notification.context).showSnackBar(
              const SnackBar(
                content: Text('Scroll metrics changed!'),
              ),
            );
            return false;
          },
          child: Scrollbar(
            isAlwaysShown: true,
            child: SizedBox(
              height: 100.0,
              width: double.infinity,
              child: const SingleChildScrollView(
                child: FlutterLogo(
                  size: 300.0,
                ),
              ),
            ),
          ),
        ),
        floatingActionButton: Container(
          padding: const EdgeInsets.all(50.0),
          child: Row(
            children: [
              FloatingActionButton.extended(
                onPressed: () => {
                  ScaffoldMessenger.of(context).showMaterialBanner(
                    MaterialBanner(
                      content: const Text('Yay!! Do you like me!!'),
                      leading: const Icon(Icons.warning),
                      backgroundColor: Colors.purple,
                      actions: [
                        TextButton(
                          child: const Text('Dismiss',
                              style: const TextStyle(color: Colors.white)),
                          onPressed: () => ScaffoldMessenger.of(context)
                              .hideCurrentMaterialBanner(),
                        ),
                      ],
                    ),
                  )
                },
                tooltip: 'Show MaterialBanner',
                label: Text("Show MaterialBanner"),
                icon: const Icon(Icons.add),
              ),
            ],
          ),
        ));
  }
}


image.png

Flutter 2.5 中的其他显著特性

除了上述新的 UI 功能外,Flutter 2.5 还引入了对可切换键盘快捷键的支持、改进的小部件检查器工具、支持在 VS Code 项目中添加依赖项以及新的应用程序模板。


让我们仔细看看。

可切换的键盘快捷键

2.5 版对 Flutter 的文本编辑键盘快捷键进行了一些更新。最值得注意的变化是快捷方式现在可以覆盖。Flutter 2.5 中新的可覆盖键盘快捷键使您能够设置快捷键组合以执行自定义操作。

改进的小部件检查器

Flutter部件检查得到了与 flutter2.5 的发布一个重大改版。新的和改进的小部件检查器现在可以更详细地查看您的小部件,包括深入了解为什么特定的帧可能会卡顿。


检查框架揭示了帧信息,包括帧的,,,和。Frame Time (UI)``Frame Time(Raster)``Jank``Shader Compilation

向 VS Code 项目添加依赖项

Flutter 插件对 Visual Studio Code 和 IntelliJ 的支持也随着 Flutter 进行了更新。现在可以从 Flutter 插件向项目添加新的依赖项。


这是通过以下命令完成的:


新应用模板

最初,当您使用flutter create app. 计数器模板的问题在于它没有为构建真实世界的应用程序提供一个好的起点。


Flutter 2.5 引入了一个具有生产级质量特性的新模板,包括:


  • 主题化
  • 页面导航
  • 本地化和国际化
  • 不同手机像素的示例图像


要在搭建新 Flutter 项目时使用这个新模板,请运行以下命令:


flutter create -t skeleton app


好的,今天关于 flutter2.5 的新特性就介绍到这儿,谢谢大家的阅读!

相关文章
|
缓存 Dart Linux
Flutter 2.8 的新特性【Flutter 专题 20】
昨天北风摇曳,我们等来了 flutter2.8 的更新,看他的介绍,说是更快速、更高效,接下来一起看一下吧 原文链接:medium.com/flutter/wha… 欢迎来到 Flutter 2.8!该版本包含了 207 位 contributors 和 178 位 reviewers 的内容,其中一共有 2,424 个合并的 PR,并 Closed 了 2976 个问题。
196 0
Flutter 2.8 的新特性【Flutter 专题 20】
|
12天前
|
缓存 监控 前端开发
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
【4月更文挑战第30天】本文探讨了Flutter应用启动优化策略,包括理解启动过程、资源加载优化、减少初始化工作、界面布局简化、异步初始化、预加载关键数据、性能监控分析以及案例和未来优化方向。通过这些方法,可以缩短启动时间,提升用户体验。使用Flutter DevTools等工具可助于识别和解决性能瓶颈,实现持续优化。
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
|
12天前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
【4月更文挑战第30天】对比 Flutter(Dart,强类型,Google支持,快速热重载,高性能渲染)与 React Native(JavaScript,庞大生态,热重载,依赖原生渲染),文章讨论了开发语言、生态系统、性能、开发体验、学习曲线、社区支持及项目选择因素。两者各有优势,选择取决于项目需求、团队技能和长期维护考虑。参考文献包括官方文档和性能比较文章。
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
|
12天前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
12天前
|
Dart 前端开发 测试技术
【Flutter前端技术开发专栏】Flutter开发中的代码质量与重构实践
【4月更文挑战第30天】随着Flutter在跨平台开发的普及,保证代码质量成为开发者关注的重点。优质代码能确保应用性能与稳定性,提高开发效率。关键策略包括遵循最佳实践,编写可读性强的代码,实施代码审查和自动化测试。重构实践在项目扩展时尤为重要,适时重构能优化结构,降低维护成本。开发者应重视代码质量和重构,以促进项目成功。
【Flutter前端技术开发专栏】Flutter开发中的代码质量与重构实践
|
12天前
|
存储 缓存 监控
【Flutter前端技术开发专栏】Flutter中的列表滚动性能优化
【4月更文挑战第30天】本文探讨了Flutter中优化列表滚动性能的策略。建议使用`ListView.builder`以节省内存,避免一次性渲染所有列表项。为防止列表项重建,可使用`UniqueKey`或`ObjectKey`。缓存已渲染项、减少不必要的重绘和异步加载大数据集也是关键。此外,选择轻量级组件,如`StatelessWidget`,并利用Flutter DevTools监控性能以识别和解决瓶颈。持续测试和调整以提升用户体验。
【Flutter前端技术开发专栏】Flutter中的列表滚动性能优化
|
12天前
|
Dart 前端开发 安全
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
【4月更文挑战第30天】本文探讨了Flutter中线程管理和并发编程的关键性,强调其对应用性能和用户体验的影响。Dart语言提供了`async`、`await`、`Stream`和`Future`等原生异步支持。Flutter采用事件驱动的单线程模型,通过`Isolate`实现线程隔离。实践中,可利用`async/await`、`StreamBuilder`和`Isolate`处理异步任务,同时注意线程安全和性能调优。参考文献包括Dart异步编程、Flutter线程模型和DevTools文档。
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
|
12天前
|
Dart 前端开发 开发者
【Flutter前端技术开发专栏】Flutter中的性能分析工具Profiler
【4月更文挑战第30天】Flutter Profiler是用于性能优化的关键工具,提供CPU、GPU、内存和网络分析。它帮助开发者识别性能瓶颈,如CPU过度使用、渲染延迟、内存泄漏和网络效率低。通过实时监控和分析,开发者能优化代码、减少内存占用、改善渲染速度和网络请求,从而提升应用性能和用户体验。定期使用并结合实际场景与其它工具进行综合分析,是实现最佳实践的关键。
【Flutter前端技术开发专栏】Flutter中的性能分析工具Profiler
|
12天前
|
前端开发 数据处理 Android开发
【Flutter 前端技术开发专栏】Flutter 中的调试技巧与工具使用
【4月更文挑战第30天】本文探讨了Flutter开发中的调试技巧和工具,强调其在及时发现问题和提高效率上的重要性。介绍了基本的调试方法如打印日志和断点调试,以及Android Studio/VS Code的调试器和Flutter Inspector的使用。文章还涉及调试常见问题的解决、性能和内存分析等高级技巧,并通过实际案例演示调试过程。在团队协作中,有效调试能提升整体开发效率,而随着技术发展,调试工具也将持续进化。
【Flutter 前端技术开发专栏】Flutter 中的调试技巧与工具使用
|
12天前
|
Dart 前端开发 Java
【Flutter前端技术开发专栏】Flutter中的内存泄漏检测与解决
【4月更文挑战第30天】本文探讨了Flutter应用中的内存泄漏检测与解决方法。内存泄漏影响性能和用户体验,常见原因包括全局变量、不恰当的闭包使用等。开发者可借助`observatory`工具或`dart_inspector`插件监测内存使用。解决内存泄漏的策略包括避免长期持有的全局变量、正确管理闭包、及时清理资源、妥善处理Stream和RxDart订阅、正确 disposal 动画和控制器,以及管理原生插件资源。通过这些方法,开发者能有效防止内存泄漏,优化应用性能。
【Flutter前端技术开发专栏】Flutter中的内存泄漏检测与解决