Flutter应用缩放插件scaled_app的使用

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

Flutter应用缩放插件scaled_app的使用

简介

scaled_app 插件用于按比例缩放整个UI设计,包括按钮、图像、字体等所有小部件。通过该插件可以确保在不同设备上UI的一致性,使得250x250的方形元素能够根据屏幕宽度自动调整为占屏幕宽度的三分之二。

Before

未缩放前

After

缩放后

当我们将上述截图调整为相同的宽度时,可以看到所有元素都保持一致的比例:

Resized After

实际演示

你可以访问 Live Demo 查看实际效果。

功能特性

  • 适用于固定宽度的UI设计。
  • 可以对整个UI进行缩放,而不仅仅是部分组件。

使用方法

替换 runApprunAppScaled

这是最简单的方式,只需将 main.dart 中的 runApp 更改为 runAppScaled 并提供一个计算缩放因子的回调函数即可。

void main() {
  runAppScaled(const MyApp(), scaleFactor: (deviceSize) {
    // 设计稿中使用的屏幕宽度
    const double widthOfDesign = 375;
    return deviceSize.width / widthOfDesign;
  });
}

替换 WidgetsFlutterBindingScaledWidgetsFlutterBinding

如果你需要更灵活地控制初始化过程,可以选择这种方式:

void main() {
  ScaledWidgetsFlutterBinding.ensureInitialized(
    scaleFactor: (deviceSize) {
      // 设计稿中使用的屏幕宽度
      const double widthOfDesign = 375;
      return deviceSize.width / widthOfDesign;
    },
  );
  runApp(const MyApp());
}

使用 MediaQueryData.scale

接下来,在你的页面或路由中,可以通过 MediaQueryData.scale 来缩放尺寸、视图内边距、视图填充等属性。

class PageRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MediaQuery(
      data: MediaQuery.of(context).scale(),
      child: const Scaffold(...),
    );
  }
}

示例代码

以下是一个完整的示例,展示了如何结合以上步骤创建一个支持缩放的应用程序:

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

double scaleFactorCallback(Size deviceSize) {
  // 设计稿中使用的屏幕宽度
  const double widthOfDesign = 375;
  return deviceSize.width / widthOfDesign;
}

void main() {
  // 方法1:使用runAppScaled
  runAppScaled(const MyApp(), scaleFactor: scaleFactorCallback);

  // 方法2:使用ScaledWidgetsFlutterBinding(注释掉)
  /*
  ScaledWidgetsFlutterBinding.ensureInitialized(
    scaleFactor: scaleFactorCallback,
  );
  runApp(const MyApp());
  */
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Scaled app demo",
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: true,
        primarySwatch: Colors.purple,
        fontFamily: "Roboto",
        textTheme: const TextTheme(bodyMedium: TextStyle(fontSize: 16)),
        appBarTheme: const AppBarTheme(centerTitle: false),
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int currentPageIndex = 0;
  bool scaleMediaQueryData = true;

  @override
  Widget build(BuildContext context) {
    final originalMediaQueryData = MediaQuery.of(context).copyWith(
      textScaler: TextScaler.noScaling,
    );
    final scaledMediaQueryData = originalMediaQueryData.scale();

    return MediaQuery(
      data: scaleMediaQueryData ? scaledMediaQueryData : originalMediaQueryData,
      child: Scaffold(
        bottomNavigationBar: NavigationBar(
          onDestinationSelected: (int index) {
            setState(() {
              currentPageIndex = index;
            });
          },
          selectedIndex: currentPageIndex,
          destinations: const <Widget>[
            NavigationDestination(
              icon: Icon(Icons.toggle_on_outlined),
              label: 'Enable / disable',
            ),
            NavigationDestination(
              icon: Icon(Icons.keyboard_capslock),
              label: 'MediaQueryData',
            ),
          ],
        ),
        body: <Widget>[
          ScaledAppDemo(mediaQueryData: originalMediaQueryData),
          ScaledMediaQueryDataDemo(
            scaleMediaQueryData: scaleMediaQueryData,
            mediaQueryData: scaleMediaQueryData
                ? scaledMediaQueryData
                : originalMediaQueryData,
            onToggleScaleMediaQueryData: (value) {
              setState(() {
                scaleMediaQueryData = value;
              });
            },
          ),
        ][currentPageIndex],
      ),
    );
  }
}

通过以上步骤和示例代码,您可以轻松地将 scaled_app 集成到您的Flutter项目中,从而实现更加灵活且响应式的用户界面设计。


更多关于Flutter应用缩放插件scaled_app的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter应用缩放插件scaled_app的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用scaled_app插件来实现应用缩放的代码示例。scaled_app插件允许你根据用户的设置或设备特性来调整整个应用的缩放级别。不过需要注意的是,scaled_app并非一个官方或广泛认知的Flutter插件,这里我们假设它提供了一个类似功能的API。如果实际插件的API有所不同,请根据文档进行相应调整。

首先,确保你已经在pubspec.yaml文件中添加了scaled_app(或类似功能的插件)依赖:

dependencies:
  flutter:
    sdk: flutter
  scaled_app: ^x.y.z  # 假设的版本号,实际使用时请替换为最新版本

然后,运行flutter pub get来安装依赖。

接下来是一个简单的示例,展示如何使用这个插件来调整应用的缩放级别:

import 'package:flutter/material.dart';
import 'package:scaled_app/scaled_app.dart';  // 假设的包导入路径

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 假设我们有一个缩放比例,这里硬编码为1.5,实际使用时可以从用户设置或其他来源获取
    final double scaleFactor = 1.5;

    return ScaledApp(
      scaleFactor: scaleFactor,
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Scaled App Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Hello, World!',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 这里可以添加逻辑来动态调整缩放比例,例如通过导航到一个设置页面
                // 注意:由于ScaledApp在顶层,这里直接更改可能不会立即生效,除非重建整个应用上下文
                // 一种方法是使用Provider或其他状态管理库来全局控制缩放比例
              },
              child: Text('Change Scale'),
            ),
          ],
        ),
      ),
    );
  }
}

注意

  1. 在这个示例中,ScaledApp是一个假设的组件,用于包裹整个应用并应用缩放。实际使用时,请查阅scaled_app(或类似插件)的文档来了解正确的用法。
  2. 如果插件不支持直接包裹整个应用,你可能需要使用其他方法,如通过LayoutBuilderTransform等组件在特定部分应用缩放。
  3. 动态调整缩放比例可能需要使用状态管理库(如Provider、Riverpod、GetX等)来在全局范围内管理缩放状态。

由于scaled_app并非一个标准或广泛使用的插件名称,如果实际使用的插件API有所不同,请参考其官方文档进行调整。

回到顶部