Flutter尺寸获取与管理插件dimension的使用

Flutter 尺寸获取与管理插件 dimension 的使用

dimension 是一个用于 Flutter 的包,它引入了 Dimension/Length 类。这个类模仿了 CSS 的长度系统,并支持四种单位:px百分比vwvhvminvmax。用户需要提供约束值和屏幕尺寸以从 Length 类中获取像素值。

此外,Dimension 类还支持加减操作、minmaxclamp 函数,并且可以进行序列化和反序列化。这使得创建响应式应用变得更加容易。

快速开始

创建 Dimension 实例

var length = Length(10.0, unit: LengthUnit.percent);

获取实际的像素值

通过调用 toPX 方法来获取实际的像素值:

double px = length.toPX(
  constraint: 100, 
  screenSize: MediaQuery.of(context).size
);

其中 constraint 可以从父组件的 BoxConstraints 中获取,而 screenSize 可以通过 MediaQuery 获取。

从数字创建 Length 实例

你也可以直接从数字创建 Length 实例:

length = 10.toPXLength; // 10 像素
length = 10.toPercentLength; // 父级约束的 10%
length = 10.toVWLength; // 屏幕宽度的 10%
length = 10.toVHLength; // 屏幕高度的 10%

加减 Length

你可以对多个 Length 进行加减操作:

length = 100.toVWLength - 10.toPXLength + 20.toPercentLength;

还可以使用 min()max()clamp() 函数:

length = Dimension.max(100.toPXLength, 10.toVWLength);
length = Dimension.clamp(10.toVWLength, 100.toPXLength, 20.toPercentLength);

这些操作可以嵌套和组合使用。

DimensionSizedBox

你可以手动调用 toPX() 方法并将结果传递给 SizedBox,或者使用 DimensionSizedBox

const DimensionSizedBox({
  Key? key,
  this.width,
  this.height,
  Widget? child,
}) : super(key: key, child: child);

final Dimension? width;
final Dimension? height;

DimensionSizedBox 类似于 SizedBox,但它接受两个 Dimension 实例作为参数。

注意,如果该小部件有一个未绑定的父级 maxWidth,并且宽度参数依赖于父级(具有百分比单位),则父级 maxWidth 将被限制为屏幕宽度。这确保了此盒子始终有界,除非你使用类似 Length(double.infinite) 的东西。

序列化

任何 Dimension 实例都可以进行序列化和反序列化:

String jsonStr = json.encode(length.toJson());

然后可以通过以下方式恢复 Dimension 实例:

Dimension newLength = parseDimension(jsonStr);

示例 Demo

下面是一个完整的示例代码,展示了如何在 Flutter 应用程序中使用 dimension 包:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool toggle = true;

  late Dimension beginWidth;
  late Dimension beginHeight;
  late Dimension endWidth;
  late Dimension endHeight;

  @override
  Widget build(BuildContext context) {
    Size screenSize = MediaQuery.of(context).size;

    beginWidth = Dimension.max(20.toPercentLength, 700.toPXLength);
    beginHeight = (90.toVHLength - 10.toPXLength);

    endWidth = Dimension.clamp(200.toPXLength, 40.toVWLength, 200.toPXLength);
    endHeight = 50.toVHLength +
        10.toPercentLength -
        Dimension.min(4.toPercentLength, 40.toPXLength);

    return Scaffold(
      appBar: AppBar(
        title: Text("Dimension Demo"),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.refresh),
        onPressed: () {
          setState(() {
            toggle = !toggle;
          });
        },
      ),
      body: Container(
        alignment: Alignment.center,
        color: Colors.green,
        child: AnimatedDimensionSizedBox(
          duration: Duration(seconds: 2),
          width: toggle ? beginWidth : endWidth,
          height: toggle ? beginHeight : endHeight,
          child: Container(
            alignment: Alignment.topCenter,
            color: Colors.amberAccent,
            child: DefaultTextStyle(
              style: TextStyle(fontSize: 16, height: 1.5),
              textAlign: TextAlign.center,
              child: SingleChildScrollView(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text("Screen Size: " + screenSize.toString()),
                    Text("Begin Width: " + beginWidth.toString()),
                    Text("End Width: " + endWidth.toString()),
                    Text("Begin Width in PX: " +
                        beginWidth
                            .toPX(
                              constraint: screenSize.width,
                              screenSize: screenSize,
                            )
                            .toString() +
                        ", End Width in PX: " +
                        endWidth
                            .toPX(
                              constraint: screenSize.width,
                              screenSize: screenSize,
                            )
                            .toString()),
                    Text("Begin Height: " + beginHeight.toString()),
                    Text("End Height: " + endHeight.toString()),
                    Text("Begin Height in PX: " +
                        beginHeight
                            .toPX(
                              constraint: screenSize.height,
                              screenSize: screenSize,
                            )
                            .toString() +
                        ", End Height in PX: " +
                        endHeight
                            .toPX(
                              constraint: screenSize.height,
                              screenSize: screenSize,
                            )
                            .toString()),
                    Align(
                      alignment: Alignment.centerLeft,
                      child: DimensionSizedBox(
                        width: 50.toPercentLength,
                        height: 50.toPercentLength,
                        child: Container(
                          color: Colors.blue,
                        ),
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

这个示例展示了如何使用 dimension 包来创建响应式的布局,并演示了如何动态调整小部件的大小。


更多关于Flutter尺寸获取与管理插件dimension的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter尺寸获取与管理插件dimension的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,管理屏幕尺寸和布局尺寸是一个常见的需求。dimension 并不是一个官方的Flutter插件,但假设你提到的是一个用于尺寸获取与管理的自定义插件或者第三方库(虽然在实际Flutter生态系统中并没有广泛认知的名为 dimension 的插件),我们可以基于Flutter原生功能展示如何获取和管理尺寸。

Flutter 提供了一些内置的功能来获取屏幕尺寸以及管理布局中的尺寸。这里我们主要使用 MediaQueryLayoutBuilder 来演示。

使用 MediaQuery 获取屏幕尺寸

MediaQuery 是一个方便的 widget,用于访问媒体信息,如屏幕尺寸、方向、文本缩放比例等。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Screen Dimension Example'),
        ),
        body: Center(
          child: ScreenDimensionWidget(),
        ),
      ),
    );
  }
}

class ScreenDimensionWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 使用 MediaQueryData 获取屏幕尺寸
    final MediaQueryData mediaQueryData = MediaQuery.of(context);
    final double screenWidth = mediaQueryData.size.width;
    final double screenHeight = mediaQueryData.size.height;

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Screen Width: $screenWidth'),
        Text('Screen Height: $screenHeight'),
      ],
    );
  }
}

使用 LayoutBuilder 管理布局尺寸

LayoutBuilder 允许你根据子widget的实际布局约束来构建widget。这对于响应式布局非常有用。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Layout Dimension Example'),
        ),
        body: LayoutBuilderExample(),
      ),
    );
  }
}

class LayoutBuilderExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        // constraints.maxWidth 和 constraints.maxHeight 提供当前布局的最大宽度和高度
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Max Width: ${constraints.maxWidth.toInt()}'),
            Text('Max Height: ${constraints.maxHeight.toInt()}'),
          ],
        );
      },
    );
  }
}

结合使用 MediaQueryLayoutBuilder

有时你可能需要结合使用 MediaQueryLayoutBuilder 来实现更复杂的布局逻辑。例如,你可能想在屏幕尺寸变化时调整某些widget的布局,同时又想根据当前布局约束做进一步调整。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Combined Dimension Example'),
        ),
        body: CombinedDimensionWidget(),
      ),
    );
  }
}

class CombinedDimensionWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MediaQueryData mediaQueryData = MediaQuery.of(context);
    final double screenWidth = mediaQueryData.size.width;

    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        final double availableWidth = constraints.maxWidth;

        // 根据屏幕尺寸和布局约束调整内容
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Screen Width: $screenWidth'),
            Text('Available Width: $availableWidth'),
            // 根据屏幕宽度和可用宽度做进一步布局调整
            if (screenWidth > 600 && availableWidth > 400)
              Text('This is a large screen with enough space.'),
            else
              Text('This is either a small screen or constrained layout.'),
          ],
        );
      },
    );
  }
}

以上代码展示了如何在Flutter中使用 MediaQueryLayoutBuilder 来获取和管理屏幕尺寸与布局尺寸。如果你的 dimension 插件有特定的功能或API,你可以参考这些例子来集成和使用它。不过,基于Flutter的官方文档和生态,上述方法是处理尺寸问题的常用和推荐方式。

回到顶部