计算 widget 边界:
static Rect getWidgetBoundary(GlobalKey key, {Offset offset = Offset.zero}) {
RenderBox widgetRenderBox = key.currentContext.findRenderObject();
Offset widgetOffset = widgetRenderBox.localToGlobal(Offset.zero);
Size size = widgetRenderBox.size;
final widgetCenter =
Rect.fromLTWH(widgetOffset.dx, widgetOffset.dy, size.width, size.height).center;
return Rect.fromCenter(
center: Offset(widgetCenter.dx + offset.dx, widgetCenter.dy + offset.dy),
width: size.width,
height: size.height);
}
计算文字大小:
static Size calculateTextSize(String text, TextStyle style,{double maxWidth,StrutStyle strutStyle}) {
final constraints = BoxConstraints(
maxWidth:maxWidth?? double.infinity,
minHeight: 0.0,
minWidth: 0.0,
);
final renderParagraph = RenderParagraph(
TextSpan(
text: text,
style: style,
),
maxLines: 1,
strutStyle:strutStyle??StrutStyle.fromTextStyle(style),
textDirection: TextDirection.ltr)
..layout(constraints);
return Size(renderParagraph.getMinIntrinsicWidth(style.fontSize).ceilToDouble(),
renderParagraph.getMinIntrinsicHeight(style.fontSize).ceilToDouble());
}
这个算出来的是一行的文字占多大宽度,具体计算成显示几行,需要 知道你限定一行展示多少,然后这算成显示成几行,然后乘以行间距
container 综合容器:
class FlexibleContainer extends StatelessWidget {
final double width;
final double height;
final EdgeInsetsGeometry margin;
final EdgeInsetsGeometry padding;
final Color borderColor;
final double borderWidth;
final BorderRadiusGeometry radius;
final Color color;
final DecorationImage image;
final List<BoxShadow> shadows;
final Alignment alignment;
final bool needClip;
final BoxShape shape;
final Gradient gradient;
final BoxConstraints constraints;
final Widget child;
FlexibleContainer(
{Key key,
this.width,
this.height,
this.constraints,
this.margin,
this.padding,
this.borderColor,
this.borderWidth = 1.0,
this.shape = BoxShape.rectangle,
this.color,
this.radius = BorderRadius.zero,
this.gradient,
this.shadows,
this.alignment,
this.needClip = false,
this.image,
this.child})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: height,
width: width,
margin: margin,
padding: padding,
constraints: constraints,
alignment: alignment ?? Alignment.center,
decoration: BoxDecoration(
gradient: gradient,
border: borderColor == null
? null
: Border.all(
color: borderColor,
width: borderWidth,
style: BorderStyle.solid,
),
shape: shape,
borderRadius: (shape == BoxShape.rectangle) ? (radius ?? BorderRadius.zero) : null,
boxShadow: shadows,
image: image,
color: color),
child: needClip
? (shape == BoxShape.circle
? ClipOval(
child: child,
)
: ClipRRect(
borderRadius: radius,
child: child,
))
: child);
}
}
使用overlay 实现自定义toast:
/**
*tips 要显示的文字
*key 需要设置显示的地方位于某个widget的下方的key,
**/
static Future showOverlayTips(BuildContext context, String tips, {Key key}) async {
OverlayEntry overlayEntry;
final screenSize = MediaQuery.of(context).size;
double top = screenSize.height * 0.7;
if (key != null) {
final anchor = WidgetUtils.getWidgetBoundary(key);
top = anchor.height;
}
final textStyle =
TextStyle(color: Color(0xffffffff), fontSize: 11, fontWeight: FontWeight.w500);
overlayEntry = OverlayEntry(builder: (BuildContext context) {
return Positioned(
top: top,
child: Material(
child: Container(
width: screenSize.width,
alignment: Alignment.center,
child: Center(
child: Card(
elevation: null,
borderOnForeground: false,
shadowColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
color: Color(0x33000000),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 5),
child: Text(
tips,
style: textStyle,
),
),
),
),
),
));
});
Overlay.of(context).insert(overlayEntry);
Future.delayed(Duration(seconds: 2), () {
overlayEntry.remove();
});
}
计算文字占用宽度
static int calculateMaxLines(BuildContext context, String text, TextStyle style, double maxWidth,
{TextAlign? textAlign, TextDirection? textDirection, StrutStyle? strutStyle}) {
int lines = 1;
late TextPainter textPainter;
do {
textPainter = TextPainter(
textAlign: textAlign ?? TextAlign.left,
textDirection: textDirection ?? TextDirection.ltr,
locale: Localizations.localeOf(
context,
),
text: TextSpan(text: text, style: style),
strutStyle: strutStyle,
maxLines: lines);
textPainter.layout(maxWidth: maxWidth);
if ((textPainter.didExceedMaxLines || textPainter.width > maxWidth)) {
lines++;
}
} while ((textPainter.didExceedMaxLines || textPainter.width > maxWidth));
return lines;
}