一起来学Flutter: 使用Decoration设置背景

Decoration

Decoration是一个抽象类,用于背景装饰的描述。Decoration有4个具体的实现类,分别是:

BoxDecoration
ShapeDecoration
FlutterLogoDecoration
UnderlineTabIndicator

BoxDecoration

BoxDecoration({
  this.color,
  this.image,
  this.border,
  this.borderRadius,
  this.boxShadow,
  this.gradient,
  this.backgroundBlendMode,
  this.shape = BoxShape.rectangle,
}),
  • color:背景颜色,这里需要注意一点:BoxDecoration中的color不能与Container中的color共存,二者只能存在一个。其实通过源码可以发现,Container中的color最后也是调用的Decoration中的color。
  • image:背景图片
  • border:背景边框
  • borderRadius:边框半径
  • boxShadow:阴影
  • gradient: 渐变色
  • backgroundBlendMode:混合Mode
  • shape:背景形状

来看个例子:

Container(
  width: width * 0.5,
  padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
  decoration: BoxDecoration(
      color: Colors.white,
      border: Border.all(
          color: Color(0xFF00FFFF),
          style: BorderStyle.solid,
          width: 2.0)),
  alignment: AlignmentDirectional.center,
  child: Text('I am Container'),
)

效果图:
border.png

这里注意一点:Container中的decoration是绘制在child后面的装饰,如果设置了Container中的decoration属性,就不能再设置Container的color属性了,否则会报错。

把BoxDecoration的常用属性抽出来,封装一个常用背景的Container:

class BaseBgWidget extends StatefulWidget {
  double width;
  double height;
  Widget child; //子widget
  EdgeInsetsGeometry margin; //Container margin
  EdgeInsetsGeometry padding; //Container padding
  Color fillDefaultColor; //默认填充颜色
  Color fillActiveColor; //点击时颜色
  Color fillDisableColor; //不可点击时颜色
  Color borderColor; //边框颜色
  double borderWidth; //边框宽度
  double borderRadius; //边框角度
  List<BoxShadow> boxShadow; //Container阴影
  BoxShape shape; //background形状
  Gradient gradient; //Container颜色渐变
  final VoidCallback onPress;

  bool btnEnable; //按钮当前是否enable
  DecorationImage image; //背景图片

  BaseBgWidget(
      {Key key,
      this.width,
      this.height,
      @required this.child,
      this.margin,
      this.padding,
      this.fillDefaultColor = Colors.white,
      this.fillActiveColor = Colors.blue,
      this.fillDisableColor = Colors.grey,
      this.borderColor = Colors.white,
      this.borderWidth,
      this.borderRadius,
      this.boxShadow,
      this.shape,
      this.gradient,
      this.onPress,
      this.btnEnable = true,
      this.image})
      : super(key: key);

  @override
  _BaseBgWidgetState createState() {
    return _BaseBgWidgetState();
  }
}

class _BaseBgWidgetState extends State<BaseBgWidget> {
  Color curColor;

  @override
  void initState() {
    super.initState();
    if (widget.onPress != null && !widget.btnEnable) {
      curColor = widget.fillDisableColor;
    } else {
      curColor = widget.fillDefaultColor;
    }
  }

  @override
  void deactivate() {
    super.deactivate();
    curColor = widget.fillDefaultColor;
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        if (widget.btnEnable && widget.onPress != null) {
          widget.onPress();
        }
      },
      onTapDown: (TapDownDetails details) {
        if (widget.btnEnable && widget.onPress != null) {
          curColor = widget.fillActiveColor;
          setState(() {});
        }
      },
      onTapUp: (TapUpDetails details) {
        if (widget.btnEnable && widget.onPress != null) {
          curColor = widget.fillDefaultColor;
          setState(() {});
        }
      },
      onTapCancel: () {
        if (widget.btnEnable && widget.onPress != null) {
          curColor = widget.fillDefaultColor;
          setState(() {});
        }
      },
      child: Container(
          width: widget.width,
          height: widget.height,
          margin: widget.margin == null ? EdgeInsets.all(0.0) : widget.margin,
          padding: widget.padding == null
              ? EdgeInsets.only(
                  left: 20.0, right: 20.0, top: 10.0, bottom: 10.0)
              : widget.padding,
//        alignment: Alignment.center,
          decoration: BoxDecoration(
              //填充颜色
              color: curColor,
              //边框颜色及宽度
              border: Border.all(
                  color: widget.borderColor,
                  width: widget.borderWidth == null ? 1.0 : widget.borderWidth),
              //边框椭圆半径
              borderRadius: widget.shape != BoxShape.circle
                  ? BorderRadius.all(Radius.circular(
                      widget.borderRadius == null ? 0.0 : widget.borderRadius))
                  : null,
              //设置阴影
              boxShadow: widget.boxShadow,
              //渐变
              gradient: widget.gradient == null ? null : widget.gradient,
              image: widget.image,

              //背景形状
              shape: widget.shape == null ? BoxShape.rectangle : widget.shape),
          child: widget.child),
    );
  }

}

代码中使用:

//椭圆矩形
BaseBgWidget(
  child: Text('I am Container'),
  borderRadius: 50.0,
  borderWidth: 2.0,
  borderColor: Colors.red,
),
//边框矩形
BaseBgWidget(
  child: Text('I am Container'),
  borderColor: Colors.green,
),
//渐变
BaseBgWidget(
  child: Text('I am Container'),
  borderRadius: 5.0,
  gradient: LinearGradient(colors: [
    Color(0xffc8e6c8),
    Color(0xff81c784),
    Color(0xff66bb6a),
    Color(0xff4caf50),
  ]),
),
//阴影
BaseBgWidget(
  child: Text('I am Container'),
  margin: EdgeInsets.only(
           top: 20.0, left: 10.0, right: 10.0, bottom: 10.0),
  borderColor: Colors.black,
  borderWidth: 0.5,
  boxShadow: [
    BoxShadow(color: Colors.grey,
              blurRadius: 10.0, //边缘会被模糊
              //spreadRadius: 10.0, //边缘不模糊
              offset: Offset(0.0, 0.0))
        ],
  ),
//不可点击
BaseBgWidget(
  child: Text(
    '不可点击状态',
    style: TextStyle(color: Colors.white),
  ),
  borderRadius: 5.0,
  margin: EdgeInsets.only(
      top: 10.0, left: 10.0, right: 10.0, bottom: 10.0),
  fillDefaultColor: Colors.green,
  fillActiveColor: Colors.blue,
  fillDisableColor: Colors.grey,
  btnEnable: false,
  onPress: () {
    CommonUtils.showToast(context, '我被点击了');
  },
),
//可点击事件
BaseBgWidget(
  child: Text(
    '可点击状态',
    style: TextStyle(color: Colors.white),
  ),
  borderRadius: 5.0,
  margin: EdgeInsets.only(
      top: 10.0, left: 10.0, right: 10.0, bottom: 10.0),
  fillDefaultColor: Colors.green,
  fillActiveColor: Colors.blue,
  onPress: () {
    CommonUtils.showToast(context, '我被点击了');
  },
),
//圆形图片背景
BaseBgWidget(
  child: Center(
    child: Text('戈哈呀', style: TextStyle(color: Colors.white)),
  ),
  onPress: () {
    CommonUtils.showToast(context, '我被点击了');
  },
  margin: EdgeInsets.all(10.0),
  width: 120.0,
  height: 120.0,
  shape: BoxShape.circle,
  borderWidth: 2.0,
  borderColor: Colors.red,
  image: new DecorationImage(
    image: new ExactAssetImage('assets/images/icon_photo.jpeg'),
    fit: BoxFit.cover,
  ),
),

decoration整体效果图:
decoration.jpg

ShapeDecoration

ShapeDecoration中的属性

ShapeDecoration({
  this.color,
  this.image,
  this.gradient,
  this.shadows,
  @required this.shape,
})
  • color:背景色,同BoxDecoration
  • image:背景图片,同BoxDecoration
  • gradient:渐变,同BoxDecoration
  • shadows:阴影,同BoxDecoration
  • shape:背景形状

来看个例子:

Container(
  width: 200.0,
  padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
  decoration: ShapeDecoration(
    shape: Border.all(
        color: Color(0xFF00FFFF),
        style: BorderStyle.solid,
        width: 2.0),
  ),
  alignment: AlignmentDirectional.center,
  child: Text('I am Container'),
)

效果图:
border.png

FlutterLogoDecoration

FlutterLogoDecoration中的属性:

FlutterLogoDecoration({
  this.lightColor = const Color(0xFF42A5F5), // Colors.blue[400]
  this.darkColor = const Color(0xFF0D47A1), // Colors.blue[900]
  this.textColor = const Color(0xFF616161),
  this.style = FlutterLogoStyle.markOnly,
  this.margin = EdgeInsets.zero,
})

直接添加flutter的Logo:

Container(
  width: 50.0,
  height: 50.0,
  decoration: FlutterLogoDecoration(
      lightColor: Colors.brown,
      darkColor: Colors.green,
      textColor: Colors.white),
  child: Text(''),
)

UnderlineTabIndicator

UnderlineTabIndicator({
  this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
  this.insets = EdgeInsets.zero,
})

如给文字加下划线:

Container(
  margin: EdgeInsets.only(left: 20.0, right: 20.0),
  decoration: UnderlineTabIndicator(
      borderSide: BorderSide(color: Colors.red, width: 2.0),
      insets: EdgeInsets.fromLTRB(0, 10, 0, 0)),
  child: Text(
    'I am Container',
    softWrap: true,
  ),
)

源码

以上例子中的源码:https://github.com/crazyqiang/flutter_study

引用

【1】https://api.flutter.dev/flutter/painting/Decoration-class.html
【2】https://juejin.im/post/5b13c3e1f265da6e3d666d80

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_小马快跑_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值