Flutter设备形态构建插件form_factor_builder的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter设备形态构建插件form_factor_builder的使用

一个用于检查和根据设备形态(桌面、平板、手机)构建小部件的Flutter包。

设置

首先,使用所需的断点和一个用于跟踪当前屏幕大小的navigatorKey初始化FormFactor实例:

import 'package:form_factor_builder/form_factor_builder.dart';

final navigatorKey = GlobalKey<NavigatorState>();

FormFactor.init(
  /// 屏幕尺寸在手机和平板之间切换的断点。
  breakpoints: FormFactorBreakpoints(
    tablet: 760,
    desktop: 1200,
  ),
  /// 用于确定当前屏幕大小的全局导航键。
  navigatorKey: navigatorKey,
);

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(),
      /// 将相同的`navigatorKey`传递给应用程序的根,以便保持当前屏幕大小。
      navigatorKey: navigatorKey,
    );
  }
}

然后,可以在整个应用中进行设备形态检查:

import 'package:form_factor_builder/form_factor_builder.dart';

if (FormFactor.instance.isDesktop) {
  print('desktop');
} else if (FormFactor.instance.isMobile) {
  print('mobile');
}

FormFactorBuilder小部件可以方便地按设备形态构建不同的小部件:

import 'package:form_factor_builder/form_factor_builder.dart';

class MyWidget extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return FormFactorBuilder(
      mobileBuilder: (context) => Text('这是手机端的小部件'),
      tabletBuilder: (context) => Text('这是平板端的小部件'),
      desktopBuilder: (context) => Text('这是桌面端的小部件'),
    );
  }
}

可以指定的完整构建器列表如下:

  • builder
  • mobileBuilder
  • tabletBuilder
  • desktopBuilder

三个更具体的构建器优先于通用的builder参数。如果多个设备形态应共享相同的实现,则可以使用通用的builder参数作为默认值。

实时更新

如果你需要构建的小部件随着设备屏幕大小的变化而实时更新,例如当改变Flutter Web应用的窗口大小或旋转平板电脑时,可以在应用程序的根部添加FormFactorChangeListener小部件:

import 'package:form_factor_builder/form_factor_builder.dart';

final navigatorKey = GlobalKey<NavigatorState>();

FormFactor.init(
  breakpoints: FormFactorBreakpoints(
    tablet: 760,
    desktop: 1200,
  ),
  navigatorKey: navigatorKey,
);

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FormFactorChangeListener(
        child: Home(),
      ),
      navigatorKey: navigatorKey,
    );
  }
}

现在,所有FormFactorBuilder小部件将在屏幕大小变化时重新构建。

流式更新

你可以监听FormFactor单例上的形式因子更新流:

FormFactor.instance.stream((formFactor) {
  print(formFactor); // desktop
});

这在你想在形式因子发生变化时执行某些副作用时非常有用。例如,你可能正在查看一个仅在桌面端可用的模态窗口,而在移动端它实际上是一个独立的屏幕。为了处理这种情况,我们可以执行如下的副作用:

FormFactors? prevFormFactor;

FormFactor.instance.stream((formFactor) {
  if (formFactor == FormFactors.mobile && prevFormFactor == FormFactors.desktop) {
    Navigator.of(context).pushReplacement(...);
  }
  prevFormFactor = formFactor;
});

为了使这一点更简单,你可以使用FormFactorchanges流,它提供了当前和前一个值:

FormFactor.instance.changes((formFactors) {
  if (formFactors.current == FormFactors.mobile && formFactors.previous == FormFactors.desktop) {
    Navigator.of(context).pushReplacement(...);
  }
});

欢迎反馈

如果您有任何问题或改进建议,请访问GitHub并告知我们。


完整示例Demo

以下是完整的示例代码:

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

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey();

  [@override](/user/override)
  initState() {
    super.initState();

    FormFactor.init(
      navigatorKey: _navigatorKey,
      breakpoints: FormFactorBreakpoints(
        tablet: 760,
        desktop: 1200,
      ),
    );

    FormFactor.instance.changes.listen((values) {
      // 忽略: 避免打印
      print('Form factor changed from ${values.current} to ${values.previous}');
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: _navigatorKey,
      home: FormFactorChangeListener(
        child: Scaffold(
          body: Center(
            child: FormFactorBuilder(
              mobileBuilder: (_context) => const Text('手机端小部件'),
              tabletBuilder: (_context) => const Text('平板端小部件'),
              desktopBuilder: (_context) => const Text('桌面端小部件'),
            ),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter设备形态构建插件form_factor_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter设备形态构建插件form_factor_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 form_factor_builder 插件在 Flutter 中根据设备形态构建不同 UI 的代码案例。

首先,确保你已经在 pubspec.yaml 文件中添加了 form_factor_builder 依赖:

dependencies:
  flutter:
    sdk: flutter
  form_factor_builder: ^latest_version  # 请替换为最新的版本号

然后,运行 flutter pub get 来获取依赖。

接下来,你可以在你的 Flutter 应用中使用 FormFactorBuilder 来根据设备形态(如手机、平板等)构建不同的 UI。以下是一个简单的示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Form Factor Builder Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FormFactorBuilder(
        builder: (context, formFactor) {
          if (formFactor == FormFactor.phone) {
            return PhoneLayout();
          } else if (formFactor == FormFactor.tablet) {
            return TabletLayout();
          } else if (formFactor == FormFactor.desktop) {
            return DesktopLayout();
          } else {
            return Scaffold(
              appBar: AppBar(
                title: Text('Unknown Form Factor'),
              ),
              body: Center(
                child: Text('Unknown Form Factor'),
              ),
            );
          }
        },
      ),
    );
  }
}

class PhoneLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Phone Layout'),
      ),
      body: Center(
        child: Text('This is the phone layout'),
      ),
    );
  }
}

class TabletLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Tablet Layout'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('This is the tablet layout'),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {},
            child: Text('Button'),
          ),
        ],
      ),
    );
  }
}

class DesktopLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Desktop Layout',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Desktop Layout'),
        ),
        body: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            Text('This is the desktop layout'),
            ElevatedButton(
              onPressed: () {},
              child: Text('Button 1'),
            ),
            ElevatedButton(
              onPressed: () {},
              child: Text('Button 2'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,FormFactorBuilder 根据设备的形态(FormFactor.phoneFormFactor.tabletFormFactor.desktop)构建不同的布局。如果设备形态未知,它会显示一个默认的占位布局。

  • PhoneLayout 是一个简单的中心对齐的文本。
  • TabletLayout 在中心显示文本,并添加了一个按钮。
  • DesktopLayout 使用了不同的主题颜色,并在一行中显示文本和两个按钮。

这样,你就可以根据设备的不同形态来提供不同的用户界面了。

回到顶部