Flutter动态尺寸管理插件dimensions_theme的使用

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

Flutter动态尺寸管理插件dimensions_theme的使用

dimensions_theme 插件为 Flutter 提供了一种方便的方式来定义和访问应用中的尺寸,如空白间距、内边距、圆角等。通过使用主题扩展,可以更轻松地管理和维护这些尺寸。

定义你的尺寸

使用单个枚举

你可以使用一个枚举来定义你的尺寸:

enum Dimension {
  xlarge,
  large,
  medium,
  small,
  xsmall,
}

MaterialApp(
  theme: ThemeData(
    extensions: const [
      DimensionsTheme({
        Dimension.xlarge: 20,
        Dimension.large: 16,
        Dimension.medium: 12,
        Dimension.small: 8,
        Dimension.xsmall: 4,
      }),
    ],
  ),
);

使用多个枚举

你也可以使用多个枚举来定义不同类型的尺寸,这在需要对不同类型的尺寸进行分类时非常有用:

enum Space {
  xlarge,
  large,
  medium,
  small,
  xsmall,
}

enum Padding {
  xlarge,
  large,
  medium,
  small,
  xsmall,
  screen,
}

MaterialApp(
  theme: ThemeData(
    extensions: const [
      DimensionsTheme({
        Space.xlarge: 20,
        Space.large: 16,
        Space.medium: 12,
        Space.small: 8,
        Space.xsmall: 4,

        Padding.xlarge: 20,
        Padding.large: 16,
        Padding.medium: 12,
        Padding.small: 8,
        Padding.xsmall: 4,
        Padding.screen: 20,
      }),
    ],
  ),
);

使用尺寸值

你可以通过 get 方法来访问定义的尺寸值:

Dimensions.of(context).get(Dimension.small);

内边距

padding 上下文扩展可以帮助你构建 EdgeInsets,使用定义的尺寸值:

Padding(
  padding: context.padding.all(Dimension.small),
  child: ...,
)

你还可以使用其他 EdgeInsets 构造函数的变体:

context.padding.all(Dimension.small)

context.padding.symmetric(
  horizontal: Dimension.medium,
  vertical: Dimension.small,
)

context.padding.only(
  left: Dimension.large,
  top: Dimension.large,
)

空白间距

Space 小部件可以根据定义的尺寸值创建 SizedBox

Column(
  children: [
    SomeWidget(),
    Space(Dimension.small),
    SomeWidget(),
  ],
)

你也可以使用 SpaceDimensionsMixin 直接从你的尺寸枚举中构建 Space 小部件:

enum Spaces with SpaceDimensionsMixin {
  large,
  medium,
  small,
}

Column(
  children: [
    SomeWidget(),
    Spaces.small(),
    SomeWidget(),
  ],
)

所有 Space 小部件都提供了 .w.h 构造函数,分别用于限制宽度和高度:

Space.h(Dimension.small)
Space.w(Dimension.small)

Spaces.small.h()
Spaces.small.w()

圆角

radius 上下文扩展可以帮助你构建 Radius,使用定义的尺寸值:

Container(
  decoration: BoxDecoration(
    borderRadius: BorderRadius.all(
      context.radius.circular(Dimension.large),
    ),
  ),
)

你还可以使用其他 Radius 构造函数的变体:

context.radius.elliptical(Dimension.large);
context.radius.circular(Dimension.small, Dimension.large);

该扩展还提供了 BorderRadius.circular() 的变体:

Container(
  decoration: BoxDecoration(
    borderRadius: borderRadius.circular(Dimension.large),
  ),
)

示例代码

以下是一个完整的示例代码,展示了如何使用 dimensions_theme 插件:

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

enum Dimension with SpaceDimensionsMixin {
  largest,
  larger,
  large,
  medium,
  small,
  smaller,
  smallest,
}

void main() {
  runApp(
    MaterialApp(
      title: "dimensions_theme example",
      theme: ThemeData(
        extensions: const [
          DimensionsTheme({
            Dimension.largest: 30,
            Dimension.larger: 24,
            Dimension.large: 20,
            Dimension.medium: 16,
            Dimension.small: 8,
            Dimension.smaller: 4,
            Dimension.smallest: 2,
          }),
        ],
      ),
      home: const DimensionsThemeExample(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(100),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Outlined(child: Dimension.largest()),
                const Space(Dimension.small),
                Outlined(child: Dimension.larger()),
                const Space(Dimension.small),
                Outlined(child: Dimension.large()),
                const Space(Dimension.small),
                Outlined(child: Dimension.medium()),
                const Space(Dimension.small),
                Outlined(child: Dimension.small()),
                const Space(Dimension.small),
                Outlined(child: Dimension.smaller()),
                const Space(Dimension.small),
                Outlined(child: Dimension.largest()),
              ],
            ),
            Dimension.largest(),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).all(Dimension.largest),
                ),
                const Space(Dimension.largest),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).all(Dimension.larger),
                ),
                const Space(Dimension.larger),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).all(Dimension.large),
                ),
                const Space(Dimension.large),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).all(Dimension.medium),
                ),
                const Space(Dimension.medium),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).all(Dimension.small),
                ),
                const Space(Dimension.small),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).all(Dimension.smaller),
                ),
                const Space(Dimension.smaller),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).all(Dimension.smallest),
                ),
              ],
            ),
            const Space(Dimension.large),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).all(Dimension.medium),
                ),
                const Space(Dimension.medium),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).only(left: Dimension.medium),
                ),
                const Space(Dimension.medium),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).only(right: Dimension.medium),
                ),
                const Space(Dimension.medium),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).only(bottom: Dimension.medium),
                ),
                const Space(Dimension.medium),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).only(top: Dimension.medium),
                ),
                const Space(Dimension.medium),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context)
                      .symmetric(vertical: Dimension.medium),
                ),
                const Space(Dimension.medium),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context)
                      .symmetric(horizontal: Dimension.medium),
                ),
              ],
            ),
            const Space(Dimension.large),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).only(
                    left: Dimension.medium,
                    top: Dimension.large,
                    right: Dimension.small,
                    bottom: Dimension.smallest,
                  ),
                ),
                const Space(Dimension.medium),
                OutlinedPadding(
                  padding: EdgeInsetsOf(context).symmetric(
                    horizontal: Dimension.largest,
                    vertical: Dimension.small,
                  ),
                ),
              ],
            ),
            const Space(Dimension.large),
            const Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Outlined(
                  radius: Dimension.largest,
                  width: Dimension.largest,
                  child: Space(Dimension.largest),
                ),
                Space(Dimension.largest),
                Outlined(
                    radius: Dimension.larger,
                    width: Dimension.larger,
                    child: Space(Dimension.larger)),
                Space(Dimension.larger),
                Outlined(
                  radius: Dimension.large,
                  width: Dimension.large,
                  child: Space(Dimension.large),
                ),
                Space(Dimension.large),
                Outlined(
                  radius: Dimension.medium,
                  width: Dimension.medium,
                  child: Space(Dimension.medium),
                ),
                Space(Dimension.medium),
                Outlined(
                  radius: Dimension.small,
                  width: Dimension.small,
                  child: Space(Dimension.small),
                ),
                Space(Dimension.small),
                Outlined(
                  radius: Dimension.smaller,
                  width: Dimension.smaller,
                  child: Space(Dimension.smaller),
                ),
                Space(Dimension.smaller),
                Outlined(
                  radius: Dimension.smallest,
                  width: Dimension.smallest,
                  child: Space(Dimension.smallest),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class Outlined extends StatelessWidget {
  const Outlined({
    super.key,
    required this.child,
    this.width,
    this.radius,
  });

  final Widget child;
  final Dimension? width;
  final Dimension? radius;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.black,
          width: DimensionsTheme.of(context).get(width ?? Dimension.small),
        ),
        borderRadius: BorderRadius.circular(
          DimensionsTheme.of(context).get(radius ?? Dimension.small),
        ),
      ),
      child: child,
    );
  }
}

class OutlinedPadding extends StatelessWidget {
  const OutlinedPadding({
    super.key,
    required this.padding,
  });

  final EdgeInsetsGeometry padding;

  @override
  Widget build(BuildContext context) {
    return Outlined(
      child: Padding(
        padding: padding,
        child: Container(
          color: const Color.fromARGB(255, 194, 194, 194),
          height: 50,
          width: 50,
        ),
      ),
    );
  }
}

通过这个示例,你可以看到如何在 Flutter 应用中使用 dimensions_theme 插件来管理各种尺寸。希望这对你的项目有所帮助!


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

1 回复

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


在Flutter中,dimensions_theme 是一个用于动态尺寸管理的插件,它允许你在应用中灵活地定义和使用尺寸。下面是一个如何使用 dimensions_theme 的示例代码案例,包括如何设置和引用尺寸。

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 dimensions_theme 依赖:

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

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

2. 配置 DimensionsTheme

在你的 MaterialAppCupertinoApp 中,使用 DimensionsThemeProvider 来包装你的应用,并定义尺寸。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DimensionsThemeProvider(
      defaultDimensions: Dimensions.builder()
        ..set('spacingSmall', 8.0)
        ..set('spacingMedium', 16.0)
        ..set('spacingLarge', 24.0)
        ..set('fontSizeSmall', 12.0)
        ..set('fontSizeMedium', 16.0)
        ..set('fontSizeLarge', 20.0),
      child: MaterialApp(
        home: HomeScreen(),
      ),
    );
  }
}

3. 使用尺寸

在你的组件中,你可以使用 useDimensions 钩子来获取并使用定义的尺寸。

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

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final dimensions = useDimensions();

    return Scaffold(
      appBar: AppBar(
        title: Text('Dimensions Theme Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Small Spacing',
              style: TextStyle(fontSize: dimensions.get('fontSizeSmall')),
            ),
            SizedBox(height: dimensions.get('spacingSmall')),
            Text(
              'Medium Spacing',
              style: TextStyle(fontSize: dimensions.get('fontSizeMedium')),
            ),
            SizedBox(height: dimensions.get('spacingMedium')),
            Text(
              'Large Spacing',
              style: TextStyle(fontSize: dimensions.get('fontSizeLarge')),
            ),
            SizedBox(height: dimensions.get('spacingLarge')),
          ],
        ),
      ),
    );
  }
}

4. 动态更改尺寸(可选)

如果你需要动态更改尺寸,你可以通过 DimensionsThemeProvider.of(context).updateDimensions 方法来更新尺寸,并在需要时刷新 UI。

// 假设你有一个按钮来更改尺寸
void _changeDimensions() {
  DimensionsThemeProvider.of(context).updateDimensions(
    Dimensions.builder()
      ..set('spacingSmall', 12.0)
      ..set('spacingMedium', 24.0)
      ..set('spacingLarge', 36.0)
      ..set('fontSizeSmall', 14.0)
      ..set('fontSizeMedium', 18.0)
      ..set('fontSizeLarge', 22.0),
  );

  // 如果你的 UI 需要立即更新,可以使用 setState 或其他方法
  // 例如,如果你在一个 StatefulWidget 中:
  // setState(() {});
}

请注意,动态更改尺寸可能需要你的组件树重新构建以反映新的尺寸。确保你的 UI 逻辑能够处理这种情况。

总结

使用 dimensions_theme 可以帮助你在 Flutter 应用中更灵活地管理尺寸,使你的代码更加清晰和可维护。通过定义和使用尺寸键,你可以轻松地在整个应用中保持一致的尺寸规范。

回到顶部