Flutter自定义控件功能扩展插件widget_modifier的使用
Flutter自定义控件功能扩展插件widget_modifier的使用
A collection of built-in flutter widget modifiers, which flatten the widget tree and make it easier to read.
Credit: 原始想法和widget_modifier的基础代码是基于@remi_rousselet的nested插件修改而成。
问题
AspectRatio(
  aspectRatio: 16 / 8,
  child: Padding(
    padding: const EdgeInsets.symmetric(horizontal: 20),
    child: DecoratedBox(
      decoration: BoxDecoration(
        color: const Color(0xFFe1e4e3),
        borderRadius: BorderRadius.circular(20),
      ),
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Row(),
      ),
    ),
  ),
)
这是一个典型的Flutter小部件。由于有四个嵌套的小部件,代码阅读起来非常困难。你需要在Padding、AspectRatio、DecoratedBox和Padding之间来回跳转才能看到实际的子小部件。这种过程既不必要又浪费脑力。
当然,在现实世界中没有人会这样做。相反,我们会使用一个友好的家伙——Container。上述小部件可以变为以下形式:
AspectRatio(
  aspectRatio: 16 / 8,
  child: Container(
    margin: const EdgeInsets.symmetric(horizontal: 20),
    decoration: BoxDecoration(
      color: const Color(0xFFe1e4e3),
      borderRadius: BorderRadius.circular(20),
    ),
    padding: const EdgeInsets.all(20),
    child: Row(),
  ),
)
但是,为什么我们仍然需要AspectRatio小部件?因为Container没有aspectRatio字段。这意味着Container无法提供所有你可能需要的配置。
为了解决这个问题,widget_modifier引入了一组新的API来“扁平化”你的小部件。
使用方法
widget_modifier提供了两种API风格:声明式和级联式。
声明式
声明式的修饰版本的上述示例小部件如下所示:
Modifier(
  modifiers: [
    AspectRatioModifier(
      aspectRatio: 16 / 8,
    ),
    PaddingModifier(
      padding: const EdgeInsets.symmetric(horizontal: 20),
    ),
    DecoratedBoxModifier(
      decoration: BoxDecoration(
        color: const Color(0xFFe1e4e3),
        borderRadius: BorderRadius.circular(20),
      ),
    ),
    PaddingModifier(
      padding: const EdgeInsets.all(20),
    )
  ],
  child: Row(),
),
modifiers: 一个List<SingleChildModifier>,基本上是一个典型的具有单个子小部件的小部件包装器。child:Modifier的子小部件。
声明式修饰器会从modifiers列表的底部元素开始应用到顶部元素。
优点与缺点
优点:
- 容易检测根
child小部件的位置。 - 代码格式良好。
 - 与编辑器代码折叠功能配合得很好。
 
缺点:
- 初学者可能会感到不直观。
 
级联式
级联式的修饰版本的上述示例小部件如下所示:
Row()
  .modified()
  .wrapWith(PaddingModifier(
    padding: const EdgeInsets.all(20),
  ))
  .wrapWith(DecoratedBoxModifier(
    decoration: BoxDecoration(
      color: const Color(0xFFe1e4e3),
      borderRadius: BorderRadius.circular(20),
    ),
  ))
  .wrapWith(PaddingModifier(
    padding: const EdgeInsets.symmetric(horizontal: 20),
  ))
  .wrapWith(AspectRatioModifier(
    aspectRatio: 16 / 8,
  ))
modified(): 扩展方法将你的小部件转换为Modifier。wrapWith(): 将SingleChildModifier插入到modifiers列表的开头。wrapWithAll(): 将List<SingleChildModifier>插入到modifiers列表的开头。
级联修饰器会从顶部的wrapWith/wrapWithAll元素开始应用到底部。
优点与缺点
优点:
- 容易检测根
child小部件的位置。 - 阅读起来更直观。
 
缺点:
- 代码格式有时看起来不够美观。
 
自定义修饰器
如果你想创建自定义修饰器,可以检查SingleChildStatelessModifier和SingleChildStatefulModifier的等效版本,它们分别是StatelessWidget和StatefulWidget。
注意事项
⚠️ 你需要覆盖buildWithChild而不是build方法。
⚠️ buildWithChild类似于build,但多了一个child参数,这是Modifier传递给SingleChildModifier的实际小部件。
⚠️ modifierKey是修饰器内部实际小部件的键。
单一状态无状态修饰器
class ConstrainedBoxModifier extends SingleChildStatelessModifier {
  ConstrainedBoxModifier({
    Key? key,
    Widget? child,
    super.modifierKey,
    required this.constraints,
  })  : assert(constraints.debugAssertIsValid()),
        super(key: key, child: child);
  final BoxConstraints constraints;
  [@override](/user/override)
  Widget buildWithChild(BuildContext context, Widget? child) {
    return ConstrainedBox(
      key: modifierKey,
      constraints: constraints,
      child: child,
    );
  }
}
单一状态有状态修饰器
你需要在SingleChildStatefulModifier的State类中实现SingleChildStateMixin混入。
class StatefulBuilderModifier extends SingleChildStatefulModifier {
  const StatefulBuilderModifier({
    super.key,
    super.modifierKey,
    required this.builder,
  });
  final SingleChildStatefulWidgetBuilder builder;
  [@override](/user/override)
  State<StatefulWidget> createState() => _StatefulBuilderModifierState();
}
class _StatefulBuilderModifierState extends State<StatefulBuilderModifier>
    with SingleChildStateMixin<StatefulBuilderModifier> {
  [@override](/user/override)
  Widget buildWithChild(BuildContext context, Widget child) {
    return widget.builder(context, setState, child);
  }
}
编辑器支持
你可以轻松地将现有的小部件转换为Modifier。更多信息请查看:

示例代码
以下是完整的示例代码:
// ignore_for_file: unused_import
import 'package:example/benchmark/benchmark_view.dart';
import 'package:example/benchmark/complex_benchmark_view.dart';
import 'package:example/benchmark/modifier_complex_benchmark_view.dart';
import 'package:example/benchmark/modifier_benchmark_view.dart';
import 'package:example/homework_reminder_ui/home_view.dart';
import 'package:example/homework_reminder_ui/modifier_home_view.dart';
import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  [@override](/user/override)
  Widget build(BuildContext context) {
    final theme = FlexColorScheme.light(
      scheme: FlexScheme.amber,
      useMaterial3: true,
    ).toTheme;
    final darkTheme = FlexColorScheme.dark(
      scheme: FlexScheme.amber,
      useMaterial3: true,
    ).toTheme;
    return MaterialApp(
      title: 'Homework tracker',
      theme: theme,
      darkTheme: darkTheme,
      themeMode: ThemeMode.light,
      home: const HomeView(),
      // home: const ModifierHomeView(),
      // home: const ModifierBenchmarkView(),
      // home: const BenchmarkView(),
      // home: const ModifierComplexBenchmarkView(),
      // home: const ComplexBenchmarkView(),
    );
  }
}
更多关于Flutter自定义控件功能扩展插件widget_modifier的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义控件功能扩展插件widget_modifier的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,自定义控件和扩展控件的功能是非常常见的需求。widget_modifier 是一个非常有用的插件,它允许你以一种链式的方式修改和扩展现有的Flutter控件。使用 widget_modifier,你可以更容易地为控件添加额外的功能,而不需要创建新的控件类。
安装 widget_modifier 插件
首先,你需要在 pubspec.yaml 文件中添加 widget_modifier 依赖:
dependencies:
  flutter:
    sdk: flutter
  widget_modifier: ^0.0.1 # 请使用最新版本
然后运行 flutter pub get 来安装依赖。
使用 widget_modifier 插件
widget_modifier 提供了 Modifier 类,你可以通过它来链式地修改控件。以下是一个简单的示例,展示了如何使用 widget_modifier 来扩展控件功能。
示例:添加边距和背景颜色
import 'package:flutter/material.dart';
import 'package:widget_modifier/widget_modifier.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Widget Modifier Example')),
        body: Center(
          child: Text('Hello, World!')
              .modifier
              .padding(all: 16.0) // 添加内边距
              .backgroundColor(Colors.blue) // 添加背景颜色
              .cornerRadius(8.0) // 添加圆角
              .build(),
        ),
      ),
    );
  }
}
在上面的示例中,我们使用了 widget_modifier 来为 Text 控件添加内边距、背景颜色和圆角。通过链式调用 modifier 的方法,我们可以轻松地扩展控件的功能。
widget_modifier 提供的一些常用方法
padding: 添加内边距margin: 添加外边距backgroundColor: 设置背景颜色cornerRadius: 设置圆角border: 添加边框shadow: 添加阴影onTap: 添加点击事件
自定义 Modifier
你还可以通过继承 Modifier 类来创建自定义的 Modifier。以下是一个自定义 Modifier 的示例:
class CustomModifier extends Modifier {
  final double customValue;
  CustomModifier({required this.customValue});
  [@override](/user/override)
  Widget build(BuildContext context, Widget child) {
    return Container(
      color: Colors.red.withOpacity(customValue),
      child: child,
    );
  }
}
// 使用自定义 Modifier
Text('Hello, World!')
    .modifier
    .custom(CustomModifier(customValue: 0.5))
    .build();
        
      
            
            
            
