Flutter自定义边框插件non_uniform_border的使用

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

Flutter自定义边框插件non_uniform_border的使用

插件介绍

non_uniform_border 是一个用于Flutter的插件,它提供了一个自定义边框类,允许为边框的每一侧设置不同的宽度,并且可以指定边框的颜色。这对于创建需要非均匀边框样式的自定义UI元素非常有用。

Image of Non-Uniform Border

开始使用

添加依赖

在你的Flutter项目的pubspec.yaml文件中添加以下依赖:

dependencies:
  non_uniform_border: ^1.0.0

然后运行flutter pub get以安装该包。

使用示例

创建非均匀边框

你可以通过导入non_uniform_border并在Dart文件中创建一个新的NonUniformBorder实例来使用这个自定义边框类。下面是一个简单的例子,展示了如何创建一个具有不同宽度和圆角的非均匀边框:

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Create a non-uniform border with different widths and radius.
    final shapeBorder = NonUniformBorder(
      leftWidth: 4,
      rightWidth: 8,
      topWidth: 12,
      bottomWidth: 16,
      color: Color(0xfffbbf24),
      side: BorderSide.strokeAlignCenter,
      borderRadius: BorderRadius.horizontal(
        left: Radius.circular(50),
        right: Radius.circular(100),
      ),
    );

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Non Uniform Border Example')),
        body: Center(
          child: Container(
            width: 300,
            height: 200,
            decoration: ShapeDecoration(
              color: Color(0xffa3e635),
              shape: shapeBorder,
            ),
          ),
        ),
      ),
    );
  }
}

创建对称边框

你也可以创建一个对称的非均匀边框,其中垂直和水平方向上的边框宽度不同:

final shapeBorderSymmetrical = NonUniformBorder.symmetrical(
  verticalWidth: 8,
  horizontalWidth: 4,
  color: Color(0xffec4899),
);

创建统一边框

如果你想要所有边都有一样的宽度,可以使用all方法:

final shapeBorderAll = NonUniformBorder.all(
  width: 2,
  color: Color(0xff00ff00),
);

示例代码

接下来是一个更复杂的例子,展示如何结合动画效果使用NonUniformBorder

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

// Inspired by Flutter's BorderSide.0.test
void main() => runApp(const StrokeAlignApp());

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: StrokeAlignExample());
  }
}

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

  @override
  State<StrokeAlignExample> createState() => _StrokeAlignExampleState();
}

class _StrokeAlignExampleState extends State<StrokeAlignExample>
    with TickerProviderStateMixin {
  late final AnimationController animation;

  @override
  void initState() {
    super.initState();
    animation =
        AnimationController(vsync: this, duration: const Duration(seconds: 1));
    animation.repeat(reverse: true);
    animation.addListener(_markDirty);
  }

  @override
  void dispose() {
    animation.dispose();
    super.dispose();
  }

  void _markDirty() {
    setState(() {});
  }

  static const double borderWidth = 10;
  static const double cornerRadius = 10;
  static const Color borderColor = Color(0x8000b4fc);

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            BorderedBox(
              shape: NonUniformBorder(
                color: borderColor,
                leftWidth: borderWidth,
                rightWidth: borderWidth,
                topWidth: borderWidth * animation.value * 2,
                bottomWidth: borderWidth * animation.value * 2,
                strokeAlign: (animation.value * 2) - 1,
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(cornerRadius * animation.value * 2),
                  topRight: Radius.circular(cornerRadius * animation.value * 2),
                  bottomLeft:
                      Radius.circular(cornerRadius * animation.value / 2),
                  bottomRight:
                      Radius.circular(cornerRadius * animation.value / 2),
                ),
              ),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: <Widget>[
                BorderedBox(
                  shape: NonUniformBorder(
                    color: borderColor,
                    leftWidth: borderWidth * animation.value * 2,
                    rightWidth: borderWidth * animation.value * 2,
                    topWidth: borderWidth,
                    bottomWidth: borderWidth,
                    strokeAlign: (animation.value * 2) - 1,
                  ),
                ),
                BorderedBox(
                  shape: NonUniformBorder(
                    color: borderColor,
                    leftWidth: borderWidth,
                    rightWidth: borderWidth * animation.value * 2,
                    topWidth: borderWidth * animation.value * 2,
                    bottomWidth: borderWidth,
                  ),
                ),
              ],
            ),
            Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  BorderedBox(
                    shape: NonUniformBorder(
                        color: borderColor,
                        leftWidth: borderWidth,
                        rightWidth: borderWidth * animation.value * 2,
                        topWidth: borderWidth * animation.value,
                        bottomWidth: borderWidth * animation.value * 2,
                        borderRadius: BorderRadius.circular(cornerRadius),
                        strokeAlign: 0),
                  ),
                  BorderedBox(
                    shape: NonUniformBorder(
                      color: borderColor,
                      leftWidth: borderWidth,
                      rightWidth: borderWidth,
                      topWidth: borderWidth * animation.value * 2,
                      bottomWidth: borderWidth * animation.value * 2,
                      strokeAlign: 1,
                      borderRadius: BorderRadius.only(
                        topLeft:
                            Radius.circular(cornerRadius * animation.value * 2),
                        topRight:
                            Radius.circular(cornerRadius * animation.value * 2),
                      ),
                    ),
                  ),
                ]),
          ],
        ),
      ),
    );
  }
}

class BorderedBox extends StatelessWidget {
  const BorderedBox({
    super.key,
    required this.shape,
  });

  final ShapeBorder shape;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 50,
      decoration: ShapeDecoration(
        color: const Color(0xff012677),
        shape: shape,
      ),
    );
  }
}

这个例子展示了如何将NonUniformBorder与动画结合,以实现动态变化的边框效果。每个BorderedBox小部件都有一个应用了NonUniformBorder的装饰器,这些边框的宽度和圆角会根据动画控制器的状态进行调整。

Image of Example

贡献和许可

  • 如果你发现了bug或者有功能请求,请在GitHub仓库上提交issue。
  • 欢迎贡献代码,可以通过fork仓库并提交pull request来贡献。
  • non_uniform_border插件遵循MIT许可证,可以在商业或非商业项目中自由使用。

希望这些信息对你有所帮助!如果你有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter自定义边框插件non_uniform_border的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义边框插件non_uniform_border的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,non_uniform_border 是一个 Flutter 插件,允许你创建非均匀(即不规则)的边框。这在需要自定义复杂边框样式时非常有用。下面是一个简单的示例,展示如何在 Flutter 应用中使用 non_uniform_border 插件来创建一个自定义边框的按钮。

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

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

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

接下来,在你的 Dart 文件中,你可以这样使用 NonUniformBorder 来创建一个自定义边框的按钮:

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

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

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

class CustomBorderButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border.fromBorderSide(
          BorderSide(
            color: Colors.blue,
            width: 4.0,
          ),
        ).copyWith(
          top: BorderStyle.solid,
          right: BorderStyle.dashed,
          bottom: BorderStyle.dotted,
          left: BorderStyle.double,
        ).applyNonUniformInsets(
          top: 8.0,
          right: 4.0,
          bottom: 12.0,
          left: 6.0,
        ).toBorder(),
      ),
      child: ElevatedButton(
        onPressed: () {},
        child: Text('Custom Border Button'),
        style: ButtonStyle(
          overlayColor: MaterialStateProperty.all(Colors.transparent),
        ),
      ),
    );
  }
}

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

  1. 定义依赖:确保在 pubspec.yaml 中添加了 non_uniform_border 依赖。
  2. 导入包:在 Dart 文件中导入 non_uniform_border 包。
  3. 创建自定义边框:使用 Border.fromBorderSide 方法创建一个基础边框,然后通过 copyWith 方法设置不同边的样式(实线、虚线、点线、双线)。
  4. 应用非均匀内边距:使用 applyNonUniformInsets 方法为边框的不同边设置不同的内边距。
  5. 将边框应用于按钮:将自定义边框应用于一个 ElevatedButton,并移除按钮的默认背景色以仅显示边框。

请注意,applyNonUniformInsets 方法是 non_uniform_border 插件提供的核心功能之一,它允许你为边框的不同边设置不同的内边距(虽然这个例子中我们实际上并没有严格意义上的“内边距”,但这种方法可以用于调整边框的厚度或样式在不同边上的表现)。

由于 non_uniform_border 插件的具体 API 可能会随着版本更新而变化,建议查阅最新的官方文档或源代码以获取最准确的信息。

回到顶部