Flutter - DecoratedBox(装饰容器)及内部控件使用详解

316 阅读3分钟

DecoratedBox. 可以在其子组件绘制前(或后)绘制一些装饰(Decoration),如背景、边框、渐变等

比如 这样

在这里插入图片描述

这样

在这里插入图片描述

这样

在这里插入图片描述

// DecoratedBox 的源码 
const DecoratedBox({
    super.key,
    required this.decoration, // Decoration
    this.position = DecorationPosition.background, // DecorationPosition
    super.child,
  }) : assert(decoration != null), assert(position != null);

DecorationPosition
position:此属性决定在哪里绘制Decoration,它接收DecorationPosition的枚举类型,该枚举类有两个值: background:在子组件之后绘制,即背景装饰。 foreground:在子组件之上绘制,即前景。

Decoration 主要用于装饰的类 在这里插入图片描述 原文翻译 一个框装饰的描述(一个应用于[Rect]的装饰)。 这个类提供了所有装饰的抽象接口。 具体示例参见[BoxDecoration]。 要实际绘制[装饰],使用[createBoxPainter] 方法获取[BoxPainter]。【装饰】对象可以 在盒子之间共享;[BoxPainter]对象可以缓存资源到 使绘画在特定的表面更快。

BoxDecoration

BoxDecoration({
  Color color, //颜色
  DecorationImage image,//图片
  BoxBorder border, //边框
  BorderRadiusGeometry borderRadius, //圆角
  List<BoxShadow> boxShadow, //阴影,可以指定多个
  Gradient gradient, //渐变
  BlendMode backgroundBlendMode, //背景混合模式
  BoxShape shape = BoxShape.rectangle, //形状
})

实例 1 属性 color + borderRadius

在这里插入图片描述

			Padding(
              padding: EdgeInsets.all(16),
              child: DecoratedBox(
                  decoration: BoxDecoration(
                      color:Colors.red,
                      borderRadius: BorderRadius.circular(15),//BorderRadius.all(Radius.circular(15))

                  ),
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 80.0, vertical: 18.0),
                    child: Text("Login", style: TextStyle(color: Colors.white),),
                  )
              ),
            ),

注 1 BorderRadius

BorderRadius extends BorderRadiusGeometry

BorderRadiusBorderRadiusGeometry的子类 ,通过BorderRadius来构建BoxDecoration的圆角 BorderRadius提供了一些便捷的方法

在这里插入图片描述

BorderRadius.all(Radius.circular(15))  // 四个角都是同一个值

在这里插入图片描述

BorderRadius.circular(15)  // 一种简便写法

在这里插入图片描述

BorderRadius.vertical(top:Radius.circular(5),bottom: Radius.circular(10))

horizontal 同理

实例 2 属性 image + borderRadius 在这里插入图片描述

	Padding(
              padding: EdgeInsets.all(10),
              child: DecoratedBox(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(15),//BorderRadius.all(Radius.circular(15))
                    image:DecorationImage(image: AssetImage("assets/images/caver.webp"),fit: BoxFit.fill),
                  ),
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 80.0, vertical: 18.0),
                    child: Text("Login", style: TextStyle(color: Colors.white),),
                  )
              ),
            ),

注 2 DecorationImage(image: AssetImage("assets/images/caver.webp"),fit: BoxFit.fill)

image  传入 图片即可

fit  图片的显示方式  BoxFit 是一个枚举

在这里插入图片描述

enum BoxFit {
  //通过扭曲源的纵横比来填充目标框
  fill,
  
  //对象中包含源文件的同时,使之尽可能大
  contain,

  // 尽可能小,同时仍然覆盖整个目标框。
  //要实际剪辑内容,请使用' clipBehavior: clip。hardEdge”与
  /// 这是一个[FittedBox]
  cover,

  //确保显示源的全宽度,无论如何 这是否意味着源垂直溢出目标框。
  //宽最大 ,忽视高,可能只显示一部分
  fitWidth,

  //同上 ,这个是保证高占满屏,宽度可能只有中间一部分
  fitHeight,

  //不错处理
  none,

 //在目标框内对齐源(默认为居中),如果必要时,缩小源代码以确保源代码适合盒。
 //这与' contains '相同,如果它会缩小图像,否则它会缩小图像与' none '相同。
  scaleDown,
}

实例3 borderRadius + border + color 在这里插入图片描述

	Padding(
              padding: EdgeInsets.all(10),
              child: DecoratedBox(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(15),//BorderRadius.all(Radius.circular(15))
                    border: Border.all(color: Colors.black,width: 2),
                    color: Colors.yellow[200],
                  ),
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 80.0, vertical: 18.0),
                    child: Text("Login", style: TextStyle(color: Colors.black),),
                  )
              ),
            ),

注 3 Border

源代码中 border 的属性是 BoxBorder
final BoxBorder? border;

// Border 为 BoxBorder的子类 
class Border extends BoxBorder 
Border 也提供了一些便捷的方法  这里用的是 all方法
 
const Border.symmetric({
    BorderSide vertical = BorderSide.none,
    BorderSide horizontal = BorderSide.none,
  })
  
const Border.fromBorderSide(BorderSide side)

factory Border.all({
    Color color = const Color(0xFF000000),
    double width = 1.0,
    BorderStyle style = BorderStyle.solid,
    StrokeAlign strokeAlign = StrokeAlign.inside,
  })

实例4 boxShadow + borderRadius + color

在这里插入图片描述

	Padding(
              padding: EdgeInsets.all(10),
              child: DecoratedBox(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(115),//BorderRadius.all(Radius.circular(15))
                    // border: Border.all(color: Colors.black,width: 2),
                      color: Colors.yellow[200],
                    boxShadow: <BoxShadow>[BoxShadow(
                      color: Colors.green,
                      offset: Offset(12,12),
                      blurRadius: 18,

                    )]
                  ),
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 80.0, vertical: 18.0),
                    child: Text("Login4", style: TextStyle(color: Colors.black),),
                  )
              ),
            ),

注 4 BoxShadow

  // boxShadow 接收的是一个 list 所以可以有多个BoxShadow叠加显示
  final List<BoxShadow>? boxShadow; 

在这里插入图片描述

    super.color,   // 阴影颜色
    super.offset,  // 偏移量
    super.blurRadius,  // 模糊度 (感觉这样形容比较贴切)
  final Offset offset; 

在这里插入图片描述

offset: Offset(12,12)  // 需要输入 x 和 y 的偏移量

实例5 borderRadius+ gradient(渐变)+boxShadow 在这里插入图片描述

	Padding(
              padding: EdgeInsets.all(10),
              child: DecoratedBox(
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(115),//BorderRadius.all(Radius.circular(15))
                      // border: Border.all(color: Colors.black,width: 2),
                      // color: Colors.yellow[200],
                      //colors: <Color>[Colors.red,Colors.green],
                    gradient:LinearGradient(colors:<Color>[Colors.red,Colors.green],
                        begin: Alignment.topLeft,end:  Alignment.centerLeft),
                      boxShadow: <BoxShadow>[BoxShadow(
                        color: Colors.black45,
                        offset: Offset(2,2),
                        blurRadius: 3,

                      )]
                  ),
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 80.0, vertical: 18.0),
                    child: Text("Login", style: TextStyle(color: Colors.black),),
                  )
              ),
            ),

注 5 gradient:LinearGradient

// gradient 是一个 Gradient
 final Gradient? gradient;

在这里插入图片描述 通过编辑器 可以看出来他有这三个 子类

在这里插入图片描述 通过看属性的类 ,在找子类的方法,看源码 ,发现,Flutter 所有不清楚的布局,点进去,找一找看一看 就懂了, 挺方便的, 不行就在翻译翻译注释 ,都解释的听清楚的