Flutter组件封装:Sliver 中的 Container 对应组件NSliverContainer

一、需求来源

项目中遇到一些代 Sliver 老代码,需要经常调整显示样式,感觉特别麻烦就想封装一个 Container 那样功能比较丰富的基础组件。

dart 复制代码
const NSliverContainer({
  super.key,
  required this.sliver,
  this.margin,
  this.padding,
  this.decoration,
  this.foregroundPadding,
  this.foregroundDecoration,
  this.opacity,
  this.ignoring,
  this.offstage,
});

/// 外边距
final EdgeInsetsGeometry? margin;

/// 内边距
final EdgeInsetsGeometry? padding;

/// 背景装饰器
final Decoration? decoration;

/// 前景装饰器内间距
final EdgeInsetsGeometry? foregroundPadding;

/// 前景装饰器
final Decoration? foregroundDecoration;

/// 透明度
final double? opacity;

/// 是否忽略事件
final bool? ignoring;

/// 是否 offstage
final bool? offstage;

二、使用示例

dart 复制代码
Widget buildSliverContainer() {
  return NSliverContainer(
    margin: const EdgeInsets.all(8),
    padding: const EdgeInsets.all(8),
    decoration: BoxDecoration(
      color: Colors.purple[50],
      borderRadius: const BorderRadius.all(Radius.circular(8)),
      border: Border.all(color: Colors.blue),
    ),
    foregroundPadding: const EdgeInsets.all(8),
    foregroundDecoration: BoxDecoration(
      color: Colors.green.withOpacity(0.6),
      borderRadius: const BorderRadius.all(Radius.circular(24)),
      border: Border.all(color: Colors.blue),
      image: DecorationImage(
        image: AssetImage(Assets.imagesBgJiguang),
      ),
    ),
    // opacity: 0.3,
    // offstage: true,
    sliver: SliverPadding(
      padding: const EdgeInsets.all(0.0),
      sliver: SliverList.list(
        children: [
          Text("NSliverContainer"),
          Text("NSliverContainer1"),
          Text("NSliverContainer2"),
        ],
      ),
    ),
  );
}

三、源码 NSliverContainer

dart 复制代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';

/// sliver 族 Container
class NSliverContainer extends StatelessWidget {
  const NSliverContainer({
    super.key,
    required this.sliver,
    this.margin,
    this.padding,
    this.decoration,
    this.foregroundPadding,
    this.foregroundDecoration,
    this.opacity,
    this.ignoring,
    this.offstage,
  });

  /// 外边距
  final EdgeInsetsGeometry? margin;

  /// 内边距
  final EdgeInsetsGeometry? padding;

  /// 背景装饰器
  final Decoration? decoration;

  /// 前景装饰器内间距
  final EdgeInsetsGeometry? foregroundPadding;

  /// 前景装饰器
  final Decoration? foregroundDecoration;

  /// 透明度
  final double? opacity;

  /// 是否忽略事件
  final bool? ignoring;

  /// 是否 offstage
  final bool? offstage;

  /// 子组件
  final Widget sliver;

  @override
  Widget build(BuildContext context) {
    Widget current = sliver;

    /// padding
    if (padding != null) {
      current = SliverPadding(
        padding: padding!,
        sliver: current,
      );
    }

    if (foregroundDecoration != null) {
      current = DecoratedSliver(
        decoration: foregroundDecoration!,
        position: DecorationPosition.foreground,
        sliver: current,
      );
    }

    if (foregroundPadding != null) {
      current = SliverPadding(
        padding: foregroundPadding!,
        sliver: current,
      );
    }

    /// decoration
    if (decoration != null) {
      current = DecoratedSliver(
        decoration: decoration!,
        sliver: current,
      );
    }

    /// margin(最外层)
    if (margin != null) {
      current = SliverPadding(
        padding: margin!,
        sliver: current,
      );
    }

    if (opacity != null) {
      current = SliverOpacity(
        opacity: opacity!,
        sliver: current,
      );
    }

    if (ignoring != null) {
      current = SliverIgnorePointer(
        ignoring: ignoring!,
        sliver: current,
      );
    }

    if (offstage != null) {
      current = SliverOffstage(
        offstage: offstage!,
        sliver: current,
      );
    }

    return current;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('margin', margin, defaultValue: null));
    properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
    properties.add(DiagnosticsProperty<Decoration>('bg', decoration, defaultValue: null));
    properties.add(DiagnosticsProperty<Decoration>('fg', foregroundDecoration, defaultValue: null));
    properties.add(DiagnosticsProperty<double>('opacity', opacity, defaultValue: null));
    properties.add(DiagnosticsProperty<bool>('ignoring', ignoring, defaultValue: null));
    properties.add(DiagnosticsProperty<bool>('offstage', offstage, defaultValue: null));
  }
}

最后、总结

1、NSliverContainer 基于 SliverPadding、 DecoratedSliver、 SliverOpacity、 SliverIgnorePointer、 SliverOffstage 等 sliver 官方组件组合而成,可以放心使用。

github

相关推荐
SamChan905 分钟前
在Web应用中集成PDF多语言翻译功能:PDFTranslator API实战指南
前端·python·ai·pdf·yapi·机器翻译
kyriewen19 分钟前
AI Agent 9秒删光了生产数据库——我给自己的项目做了5个紧急检查
前端·ai编程·claude
IT_陈寒30 分钟前
JavaScript的this又双叒叕让我怀疑人生了
前端·人工智能·后端
陈随易42 分钟前
MCP协议第5次更新,从打电话到微信聊天的巨大变革
前端·后端·程序员
omnijk1 小时前
前端工程化
前端
做前端的娜娜子1 小时前
前端必看!我把一段"能跑不敢动"的报表代码用 AI 重构成了组件(附完整 Prompt)
前端·ai编程
hunterandroid1 小时前
[鸿蒙从零到一] ArkUI 动画与转场实战:状态驱动、组件过渡与页面衔接
前端
何时梦醒1 小时前
React + TypeScript + Vite 实战:从零构建 Color Picker 应用
前端·javascript·架构
谁在黄金彼岸2 小时前
Nuxt.js 详解(一):Vue 开发者为什么要关注 Nuxt
前端