Flutter尺寸测量插件millimeters的使用

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

Flutter尺寸测量插件millimeters的使用

描述

millimeters 是一个Flutter插件,用于确定物理设备屏幕尺寸(以毫米为单位)。该插件依赖于本地API来提供正确的值。在Apple平台(iOS, macOS)上通常会得到正确结果(除非你正在镜像你的屏幕),但在其他平台上结果可能完全不准确。此插件尽力提供正确结果,但在某些平台(如Web、Android)上可能永远不会准确。

尽管如此,在少数情况下确实需要物理一致的尺寸,例如在WidgetBook中绘制设备框架,或者在手册中引用物理对象(通常用于打印),又或许用于二维码。需要注意的是,你不应该将用户点击和交互的常规UI设置为物理一致的大小,因为不同平台之间的典型观看距离可能会有很大差异

支持的功能

功能 Windows Linux macOS Web Android iOS
分辨率 ✔️ ✔️ ✔️ ✔️
物理尺寸 ✔️ ✔️ ✔️1 ✔️
多窗口
多显示器 ✔️
处理屏幕缩放 ✔️ ✔️

1 Web平台上的物理尺寸可能不准确。

使用方法

引入包

首先,你需要在项目中引入millimeters包。可以在pubspec.yaml文件中添加依赖:

dependencies:
  millimeters: ^latest_version # 替换为最新版本号

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

示例代码

下面是一个完整的示例代码,展示了如何使用millimeters插件创建一个简单的应用:

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

void main() {
  runApp(
    Millimeters.fromView(
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 从上下文中获取Millimeters实例
    final mm = Millimeters.of(context).mm;

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Millimeters Example'),
        ),
        body: Center(
          child: ColoredBox(
            color: Colors.blue,
            child: SizedBox.fromSize(
              // 使用mm函数将毫米转换为逻辑像素
              size: Size(mm(50), mm(50)), // 这个盒子应该有5厘米长的边。
            ),
          ),
        ),
      ),
    );
  }
}

创建更复杂的演示应用

如果你想要创建一个更复杂的应用来展示millimeters插件的功能,可以参考以下代码:

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

Future<void> main() async {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Millimeters.fromView(
      child: MaterialApp(
        theme: ThemeData.from(
          colorScheme: ColorScheme.fromSeed(
            seedColor: const Color.fromARGB(255, 61, 200, 89),
            brightness: Brightness.light,
          ),
          useMaterial3: true,
        ),
        darkTheme: ThemeData.from(
          colorScheme: ColorScheme.fromSeed(
            seedColor: const Color.fromARGB(255, 59, 158, 73),
            brightness: Brightness.dark,
          ),
          useMaterial3: true,
        ),
        debugShowCheckedModeBanner: false,
        home: const Scaffold(
          body: Demo(),
          backgroundColor: Colors.transparent,
        ),
      ),
    );
  }
}

class Demo extends StatelessWidget {
  const Demo({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    final physicalities = Millimeters.of(context);
    final mm = physicalities.mm;
    return Stack(
      children: [
        Align(
          alignment: Alignment.topRight,
          child: ColoredBox(
            color: Theme.of(context).colorScheme.surface,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text("Monitor size: $physicalities"),
            ),
          ),
        ),
        Positioned.fill(
          child: CustomPaint(
            painter: GridPainter(
              color: Theme.of(context).colorScheme.tertiary.withOpacity(0.66),
              interval: mm(50),
              divisions: 5,
              subdivisions: 10,
            ),
          ),
        ),
        Align(
          alignment: Alignment.bottomRight,
          child: Padding(
            padding: const EdgeInsets.all(32.0),
            child: ClipRRect(
                borderRadius: BorderRadius.circular(mm(23.25)),
                child: Image.asset(
                  "assets/euro.webp",
                  width: mm(23.25),
                  height: mm(23.25),
                  semanticLabel: "1 Euro coin",
                )),
          ),
        ),
        DraggableBox(
          size: const Size(50, 50).unit(mm),
          offset: const Offset(10, 10).unit(mm),
        ),
      ],
    );
  }
}

class GridPainter extends CustomPainter {
  final Color color;
  final double interval;
  final int divisions;
  final int subdivisions;

  GridPainter({
    required this.color,
    required this.interval,
    required this.divisions,
    required this.subdivisions,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint()
      ..color = color
      ..strokeWidth = 0.5;

    for (int i = 0; i <= size.width / interval; i++) {
      canvas.drawLine(
        Offset(i * interval, 0),
        Offset(i * interval, size.height),
        paint,
      );
    }

    for (int i = 0; i <= size.height / interval; i++) {
      canvas.drawLine(
        Offset(0, i * interval),
        Offset(size.width, i * interval),
        paint,
      );
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

class DraggableBox extends StatefulWidget {
  final Size size;
  final Offset offset;

  const DraggableBox({
    Key? key,
    required this.size,
    required this.offset,
  }) : super(key: key);

  @override
  _DraggableBoxState createState() => _DraggableBoxState();
}

class _DraggableBoxState extends State<DraggableBox> {
  late Offset _position = widget.offset;

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: _position.dx,
      top: _position.dy,
      child: Draggable(
        onDragUpdate: (details) {
          setState(() {
            _position += details.delta;
          });
        },
        child: Container(
          width: widget.size.width,
          height: widget.size.height,
          color: Colors.red,
        ),
      ),
    );
  }
}

以上代码创建了一个包含网格背景、可拖动方块以及显示屏幕尺寸信息的应用。你可以根据自己的需求进一步扩展和完善这个示例。


更多关于Flutter尺寸测量插件millimeters的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter尺寸测量插件millimeters的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用millimeters插件进行尺寸测量的示例代码。millimeters插件允许你将设备的屏幕物理尺寸(如毫米)转换为逻辑像素尺寸,这在某些需要精确物理尺寸的应用中非常有用。

首先,你需要在你的pubspec.yaml文件中添加millimeters依赖项:

dependencies:
  flutter:
    sdk: flutter
  millimeters: ^最新版本号  # 请替换为实际的最新版本号

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

接下来,你可以在你的Flutter应用中使用Millimeters类来进行尺寸转换。以下是一个简单的示例,展示如何使用这个插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Millimeters Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Millimeters Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                '100 millimeters in logical pixels:',
                style: TextStyle(fontSize: 20),
              ),
              SizedBox(
                height: Millimeters.fromMillimeters(100).toDouble(),
                child: Container(
                  color: Colors.blue.withOpacity(0.5),
                  child: Center(
                    child: Text(
                      '100mm',
                      style: TextStyle(color: Colors.white, fontSize: 20),
                    ),
                  ),
                ),
              ),
              SizedBox(height: 20), // Add some space between widgets
              ElevatedButton(
                onPressed: () {
                  double screenWidthMm = ScreenSizeInfo().screenWidthMm;
                  double screenHeightMm = ScreenSizeInfo().screenHeightMm;
                  print('Screen Width in MM: $screenWidthMm');
                  print('Screen Height in MM: $screenHeightMm');
                },
                child: Text('Get Screen Size in MM'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 依赖添加:在pubspec.yaml文件中添加了millimeters依赖项。
  2. 转换毫米到逻辑像素:使用Millimeters.fromMillimeters(100).toDouble()将100毫米转换为逻辑像素,并在UI中显示一个高度为100毫米的容器。
  3. 获取屏幕物理尺寸:通过ScreenSizeInfo().screenWidthMmScreenSizeInfo().screenHeightMm获取屏幕的宽度和高度(以毫米为单位),并在按钮点击时打印这些信息。

请注意,ScreenSizeInfo类可能不是millimeters插件直接提供的,这里只是为了演示如何获取屏幕的物理尺寸。实际使用中,你可能需要结合设备信息插件来获取屏幕的物理尺寸。

确保你查看millimeters插件的官方文档以获取最新和最准确的信息,因为插件的API可能会随着版本的更新而变化。

回到顶部