【发布时间】:2019-05-29 21:28:31
【问题描述】:
【问题讨论】:
-
你尝试了吗?你也可以添加那个东西吗?
-
尝试文本('------------------------------------')
-
如果您想在画布上将其绘制为虚线路径,请使用此包:pub.dartlang.org/packages/path_drawing
【问题讨论】:
感谢marksimr的回答,这是垂直和水平虚线的代码。
横向用法:
DashLineView(
fillRate: 0.7,
),
垂直用法:
DashLineView(
fillRate: 0.7,
direction: Axis.vertical,
),
完整代码:
class DashLineView extends StatelessWidget {
final double dashHeight;
final double dashWith;
final Color dashColor;
final double fillRate; // [0, 1] totalDashSpace/totalSpace
final Axis direction;
DashLineView(
{this.dashHeight = 1,
this.dashWith = 8,
this.dashColor = Colors.black,
this.fillRate = 0.5,
this.direction = Axis.horizontal});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final boxSize = direction == Axis.horizontal
? constraints.constrainWidth()
: constraints.constrainHeight();
final dCount = (boxSize * fillRate / dashWith).floor();
return Flex(
children: List.generate(dCount, (_) {
return SizedBox(
width: direction == Axis.horizontal ? dashWith : dashHeight,
height: direction == Axis.horizontal ? dashHeight : dashWith,
child: DecoratedBox(
decoration: BoxDecoration(color: dashColor),
),
);
}),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
direction: direction,
);
},
);
}
}
【讨论】:
Container(
color: Colors.white,
height: 40.0,
child: Center(
child: Text(
"---------------------------------------------------------------------------",
maxLines: 1,
style: typoNormalTextRegular.copyWith(
color: colorABGray),
),
),
),
只使用Text Widget,简单的解决方案
【讨论】:
使用dotted_line: ^3.0.0 lib,它提供虚线和更多link
import 'package:dotted_line/dotted_line.dart';
DottedLine(
direction: Axis.horizontal,
lineLength: double.infinity,
lineThickness: 1.0,
dashLength: 4.0,
dashColor: Colors.grey,
dashRadius: 0.0,
dashGapLength: 4.0,
dashGapColor: Colors.transparent,
dashGapRadius: 0.0,
)
输出:
【讨论】:
我通过整合解决方案 here 和来自 here 的数学创建了一个 CustomPainter。这个CustomPainter 允许通过指定虚线的长度和虚线之间的空间长度来绘制实线或虚线。但最好的是,您甚至可以在各个方向上绘制实线或虚线。我的意思是水平,垂直,甚至对角线!
这是CustomPainter的代码:
import 'dart:math';
import 'package:flutter/material.dart';
class LinePainter extends CustomPainter {
final Offset firstOffset;
final Offset secondOffset;
final Color color;
final double strokeWidth;
final double dashLength;
final double dashSpace;
const LinePainter({
required this.firstOffset,
required this.secondOffset,
this.color = Colors.black,
this.strokeWidth = 2.0,
this.dashLength = 4.0,
this.dashSpace = 4.0,
});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = color
..strokeWidth = strokeWidth;
_drawDashedLine(
dashLength, dashSpace, firstOffset, secondOffset, canvas, size, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
void _drawDashedLine(double dashLength, double dashSpace, Offset firstOffset,
Offset secondOffset, Canvas canvas, Size size, Paint paint) {
var startOffset = firstOffset;
var intervals = _getDirectionVector(firstOffset, secondOffset).length /
(dashLength + dashSpace);
for (var i = 0; i < intervals; i++) {
var endOffset = _getNextOffset(startOffset, secondOffset, dashLength);
/// Draw a small line.
canvas.drawLine(startOffset, endOffset, paint);
/// Update the starting offset.
startOffset = _getNextOffset(endOffset, secondOffset, dashSpace);
}
}
Offset _getNextOffset(
Offset firstOffset,
Offset secondOffset,
double smallVectorLength,
) {
var directionVector = _getDirectionVector(firstOffset, secondOffset);
var rescaleFactor = smallVectorLength / directionVector.length;
if (rescaleFactor.isNaN || rescaleFactor.isInfinite) {
rescaleFactor = 1;
}
var rescaledVector = Offset(directionVector.vector.dx * rescaleFactor,
directionVector.vector.dy * rescaleFactor);
var newOffset = Offset(
firstOffset.dx + rescaledVector.dx, firstOffset.dy + rescaledVector.dy);
return newOffset;
}
DirectionVector _getDirectionVector(Offset firstVector, Offset secondVector) {
var directionVector = Offset(
secondVector.dx - firstVector.dx, secondVector.dy - firstVector.dy);
var directionVectorLength =
sqrt(pow(directionVector.dx, 2) + pow(directionVector.dy, 2));
return DirectionVector(
vector: directionVector,
length: directionVectorLength,
);
}
}
class DirectionVector {
final Offset vector;
final double length;
const DirectionVector({
required this.vector,
required this.length,
});
}
您可以通过设置CustomPaint 小部件的painter 参数来使用此CustomPainter,如下所示:
CustomPaint(
painter: LinePainter(
firstOffset: Offset(0, 0),
secondOffset: Offset(10, 10),
),
),
结果如下图所示:
【讨论】:
你可以用这个:
Widget dashedHorizontalLine(){
return Row(
children: [
for (int i = 0; i < 20; i++)
Expanded(
child: Row(
children: [
Expanded(
child: Divider(
color: AppColors.darkGreen,
thickness: 2,
),
),
Expanded(
child: Container(),
),
],
),
),
],
);
}
【讨论】:
您可以将 CustomPainter 与 线性渐变虚线着色器 一起用于线条。
// GradientRotation(3.14 / 2) — for vertical lines with dashes
// GradientRotation(0) — for horizontal lines with dashes
// .createShader(Rect.fromLTWH(0, 0, 10, 10) — 10 is the size of repeated shaders part
// This method can be tricky if you need a line oriented by some angle.
Paint()..shader = LinearGradient(
colors: [Colors.blue, Colors.transparent],
stops: [0.5, 0.5],
tileMode: TileMode.repeated,
transform: GradientRotation(3.14 / 2))
.createShader(Rect.fromLTWH(0, 0, 10, 10))
..style = PaintingStyle.stroke
..strokeWidth = 6
【讨论】:
您应该更喜欢使用 CustomPainter,因为它具有更高的性能并且适合此类问题。
class DashLine extends StatelessWidget {
const DashLine({
Key key,
this.color,
this.dashWidth,
this.dashSpace,
this.strokeWidth,
}) : super(key: key);
final Color color;
final double dashWidth;
final double dashSpace;
final double strokeWidth;
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _DashLinePainter(
color: color,
dashWidth: dashWidth,
dashSpace: dashSpace,
strokeWidth: strokeWidth,
),
);
}
}
class _DashLinePainter extends CustomPainter {
_DashLinePainter({
Color color,
double dashWidth,
double dashSpace,
double strokeWidth,
}) : _color = color ?? Colors.red,
_dashWidth = dashWidth ?? 5.0,
_dashSpace = dashSpace ?? 5.0,
_strokeWidth = strokeWidth ?? 1.0;
final Color _color;
final double _dashWidth;
final double _dashSpace;
final double _strokeWidth;
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = _color
..strokeWidth = _strokeWidth;
var max = size.width;
var startX = 0.0;
while (max >= 0) {
canvas.drawLine(Offset(startX, 0), Offset(startX + _dashWidth, 0), paint);
final space = (_dashSpace + _dashWidth);
startX += space;
max -= space;
}
}
@override
bool shouldRepaint(_DashLinePainter oldDelegate) {
return _color != oldDelegate._color ||
_dashWidth != oldDelegate._dashWidth ||
_dashSpace != oldDelegate._dashSpace ||
_strokeWidth != oldDelegate._strokeWidth;
}
}
【讨论】:
垂直虚线:
我修改了 maksimr 的例子:
class DashedLine extends StatelessWidget {
final double height;
final double heightContainer;
final Color color;
const DashedLine({this.height = 3, this.color = Colors.black, this.heightContainer = 70});
@override
Widget build(BuildContext context) {
return Container(
height: heightContainer,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final boxHeight = constraints.constrainHeight();
final dashWidth = 10.0;
final dashHeight = height;
final dashCount = (boxHeight / (2 * dashHeight)).floor();
return Flex(
children: List.generate(dashCount, (_) {
return SizedBox(
width: dashWidth,
height: dashHeight,
child: DecoratedBox(
decoration: BoxDecoration(color: color),
),
);
}),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
direction: Axis.vertical,
);
},
),
);
}
}
【讨论】:
// garis putus putus
Row(
children: List.generate(150~/10, (index) => Expanded(
child: Container(
color: index%2==0?Colors.transparent
:Colors.grey,
height: 2,
),
)),
),
【讨论】:
创建这个类:
class DotWidget extends StatelessWidget {
final double totalWidth, dashWidth, emptyWidth, dashHeight;
final Color dashColor;
const DotWidget({
this.totalWidth = 300,
this.dashWidth = 10,
this.emptyWidth = 5,
this.dashHeight = 2,
this.dashColor = Colors.black,
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(
totalWidth ~/ (dashWidth + emptyWidth),
(_) => Container(
width: dashWidth,
height: dashHeight,
color: dashColor,
margin: EdgeInsets.only(left: emptyWidth / 2, right: emptyWidth / 2),
),
),
);
}
}
用法:
像使用任何其他小部件一样使用它
child: DotWidget(
dashColor: Colors.black,
dashHeight: 2,
dashWidth: 100,
)
【讨论】:
【讨论】:
class DashedLinePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
double dashWidth = 9, dashSpace = 5, startX = 0;
final paint = Paint()
..color = Colors.grey
..strokeWidth = 1;
while (startX < size.width) {
canvas.drawLine(Offset(startX, 0), Offset(startX + dashWidth, 0), paint);
startX += dashWidth + dashSpace;
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
【讨论】:
试试这个,
class DotDivider extends StatelessWidget {
final double width;
final double height;
final double gap;
final Color color;
final double lineHeight;
const DotDivider(
{this.height = 1.0,
this.color = Colors.black,
this.width = 2.0,
this.gap = 2.0,
this.lineHeight = 10.0});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final boxWidth = constraints.constrainWidth();
final dashWidth = width;
final dashHeight = height;
final dashCount = (boxWidth / dashWidth).floor();
return Container(
height: (lineHeight * 2) + height,
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: dashCount,
itemBuilder: (BuildContext context, int index) => Center(
child: Container(
width: dashWidth,
height: dashHeight,
margin:
EdgeInsets.symmetric(vertical: lineHeight, horizontal: gap),
decoration: BoxDecoration(color: color),
),
),
),
);
},
);
}
}
【讨论】:
这是水平虚线的代码,就像您的图像一样。 CustomPaint 是 Flutter 团队强烈推荐的。它也可以快速高效地进行渲染。您可以使用 Offset 来改变方向。
class MyClass extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: CustomPaint(
painter: MyLinePainter(),
),
);
}
}
class MyLinePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
var max = 100;
var dashWidth, dashSpace = 5;
double startX = 0;
final paint = Paint()..color = Colors.grey;
while (max >= 0) {
canvas.drawLine(Offset(startX, 0), Offset(startX + dashWidth, 0), paint..strokeWidth = 1);
final space = (dashSpace + dashWidth);
startX += space;
max -= space;
}
}
【讨论】:
CustomPainter 也可以在这里提供帮助。在此示例中是一条垂直虚线,但可以轻松更改。
class LineDashedPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()..strokeWidth = 2;
var max = 35;
var dashWidth = 5;
var dashSpace = 5;
double startY = 0;
while (max >= 0) {
canvas.drawLine(Offset(0, startY), Offset(0, startY + dashWidth), paint);
final space = (dashSpace + dashWidth);
startY += space;
max -= space;
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
并且使用 CustomPaint 小部件:
CustomPaint(painter: LineDashedPainter())
【讨论】:
As a workaround,在你的情况下,你可以这样做
class MySeparator extends StatelessWidget {
final double height;
final Color color;
const MySeparator({this.height = 1, this.color = Colors.black});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final boxWidth = constraints.constrainWidth();
final dashWidth = 10.0;
final dashHeight = height;
final dashCount = (boxWidth / (2 * dashWidth)).floor();
return Flex(
children: List.generate(dashCount, (_) {
return SizedBox(
width: dashWidth,
height: dashHeight,
child: DecoratedBox(
decoration: BoxDecoration(color: color),
),
);
}),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
direction: Axis.horizontal,
);
},
);
}
}
并使用它const MySeparator()
class App extends StatelessWidget {
const App();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Material(
child: Container(
color: Colors.blue,
child: Center(
child: Container(
height: 600, width: 350,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(16.0)),
),
child: Flex(
direction: Axis.vertical,
children: [
Expanded(child: Container()),
const MySeparator(color: Colors.grey),
Container(height: 200),
],
),
),
),
),
),
);
}
}
【讨论】: