Decoration
是一个抽象类,用于背景装饰的描述。Decoration
有4个具体的实现类,分别是:
BoxDecoration
ShapeDecoration
FlutterLogoDecoration
UnderlineTabIndicator
BoxDecoration({
this.color,
this.image,
this.border,
this.borderRadius,
this.boxShadow,
this.gradient,
this.backgroundBlendMode,
this.shape = BoxShape.rectangle,
}),
来看个例子:
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'),
)
这里注意一点: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; //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 {
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,
),
),
ShapeDecoration中的属性
ShapeDecoration({
this.color,
this.image,
this.gradient,
this.shadows,
@required this.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'),
)
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({
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