Ant*_*nko 23
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;
}
Run Code Online (Sandbox Code Playgroud)
hnn*_*lch 19
以下代码不仅为线条创建虚线路径,而且为任何想要虚线的路径创建虚线路径。
演示:
这个想法是originalPath沿着它移动,交替添加破折号和间隙,直到提取整个路径:
Path _getDashedPath(
Path originalPath,
double dashLength,
double dashGapLength,
) {
final metricsIterator = originalPath.computeMetrics().iterator;
while (metricsIterator.moveNext()) {
final metric = metricsIterator.current;
_dashedPathProperties.extractedPathLength = 0.0;
while (_dashedPathProperties.extractedPathLength < metric.length) {
if (_dashedPathProperties.addDashNext) {
_dashedPathProperties.addDash(metric, dashLength);
} else {
_dashedPathProperties.addDashGap(metric, dashGapLength);
}
}
}
return _dashedPathProperties.path;
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个类DashedPathProperties来跟踪 currentextractedPathLength或 the 等内容_remainingDashLength,如果originalPath包含多个子路径并且必须在下一个子路径上继续使用破折号(或破折号间隙),则该类将变得相关:
class DashedPathProperties {
double extractedPathLength;
Path path;
final double _dashLength;
double _remainingDashLength;
double _remainingDashGapLength;
bool _previousWasDash;
DashedPathProperties({
required this.path,
required double dashLength,
required double dashGapLength,
}) : assert(dashLength > 0.0, 'dashLength must be > 0.0'),
assert(dashGapLength > 0.0, 'dashGapLength must be > 0.0'),
_dashLength = dashLength,
_remainingDashLength = dashLength,
_remainingDashGapLength = dashGapLength,
_previousWasDash = false,
extractedPathLength = 0.0;
//...
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用(如果你想确保画家不能在边界之外绘画,你可以将你的CustomPaint包裹起来):ClipRect
CustomPaint(
painter: DashedPathPainter(
originalPath: Path()
..addOval(
const Rect.fromLTWH(0, 0, 100, 100),
),
pathColor: Colors.white,
),
size: const Size(100.0, 100.0),
)
Run Code Online (Sandbox Code Playgroud)
您可以在 DartPad 中运行的完整示例代码:
import 'dart:ui' as ui;
import 'dart:math' as math;
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: const Scaffold(
body: Center(
child: ExampleDashedPath(),
),
),
);
}
}
class ExampleDashedPath extends StatelessWidget {
const ExampleDashedPath({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(height: 50),
CustomPaint(
painter: DashedPathPainter(
originalPath: Path()..lineTo(100, 0),
pathColor: Colors.red,
strokeWidth: 5.0,
dashGapLength: 10.0,
dashLength: 10.0,
),
size: const Size(100.0, 2.0),
),
const SizedBox(height: 50),
CustomPaint(
painter: DashedPathPainter(
originalPath: Path()
..addOval(
const Rect.fromLTWH(0, 0, 100, 100),
),
pathColor: Colors.white,
),
size: const Size(100.0, 100.0),
),
const SizedBox(height: 50),
CustomPaint(
painter: DashedPathPainter(
originalPath: Path()
..addRect(
const Rect.fromLTWH(0, 0, 100, 100),
)
..lineTo(100, 100),
pathColor: Colors.grey,
strokeWidth: 2.0,
dashLength: 25.0,
),
size: const Size(100.0, 100.0),
),
],
);
}
}
class DashedPathPainter extends CustomPainter {
final Path originalPath;
final Color pathColor;
final double strokeWidth;
final double dashGapLength;
final double dashLength;
late DashedPathProperties _dashedPathProperties;
DashedPathPainter({
required this.originalPath,
required this.pathColor,
this.strokeWidth = 3.0,
this.dashGapLength = 5.0,
this.dashLength = 10.0,
});
@override
void paint(Canvas canvas, Size size) {
_dashedPathProperties = DashedPathProperties(
path: Path(),
dashLength: dashLength,
dashGapLength: dashGapLength,
);
final dashedPath = _getDashedPath(originalPath, dashLength, dashGapLength);
canvas.drawPath(
dashedPath,
Paint()
..style = PaintingStyle.stroke
..color = pathColor
..strokeWidth = strokeWidth,
);
}
@override
bool shouldRepaint(DashedPathPainter oldDelegate) =>
oldDelegate.originalPath != originalPath ||
oldDelegate.pathColor != pathColor ||
oldDelegate.strokeWidth != strokeWidth ||
oldDelegate.dashGapLength != dashGapLength ||
oldDelegate.dashLength != dashLength;
Path _getDashedPath(
Path originalPath,
double dashLength,
double dashGapLength,
) {
final metricsIterator = originalPath.computeMetrics().iterator;
while (metricsIterator.moveNext()) {
final metric = metricsIterator.current;
_dashedPathProperties.extractedPathLength = 0.0;
while (_dashedPathProperties.extractedPathLength < metric.length) {
if (_dashedPathProperties.addDashNext) {
_dashedPathProperties.addDash(metric, dashLength);
} else {
_dashedPathProperties.addDashGap(metric, dashGapLength);
}
}
}
return _dashedPathProperties.path;
}
}
class DashedPathProperties {
double extractedPathLength;
Path path;
final double _dashLength;
double _remainingDashLength;
double _remainingDashGapLength;
bool _previousWasDash;
DashedPathProperties({
required this.path,
required double dashLength,
required double dashGapLength,
}) : assert(dashLength > 0.0, 'dashLength must be > 0.0'),
assert(dashGapLength > 0.0, 'dashGapLength must be > 0.0'),
_dashLength = dashLength,
_remainingDashLength = dashLength,
_remainingDashGapLength = dashGapLength,
_previousWasDash = false,
extractedPathLength = 0.0;
bool get addDashNext {
if (!_previousWasDash || _remainingDashLength != _dashLength) {
return true;
}
return false;
}
void addDash(ui.PathMetric metric, double dashLength) {
// Calculate lengths (actual + available)
final end = _calculateLength(metric, _remainingDashLength);
final availableEnd = _calculateLength(metric, dashLength);
// Add path
final pathSegment = metric.extractPath(extractedPathLength, end);
path.addPath(pathSegment, Offset.zero);
// Update
final delta = _remainingDashLength - (end - extractedPathLength);
_remainingDashLength = _updateRemainingLength(
delta: delta,
end: end,
availableEnd: availableEnd,
initialLength: dashLength,
);
extractedPathLength = end;
_previousWasDash = true;
}
void addDashGap(ui.PathMetric metric, double dashGapLength) {
// Calculate lengths (actual + available)
final end = _calculateLength(metric, _remainingDashGapLength);
final availableEnd = _calculateLength(metric, dashGapLength);
// Move path's end point
ui.Tangent tangent = metric.getTangentForOffset(end)!;
path.moveTo(tangent.position.dx, tangent.position.dy);
// Update
final delta = end - extractedPathLength;
_remainingDashGapLength = _updateRemainingLength(
delta: delta,
end: end,
availableEnd: availableEnd,
initialLength: dashGapLength,
);
extractedPathLength = end;
_previousWasDash = false;
}
double _calculateLength(ui.PathMetric metric, double addedLength) {
return math.min(extractedPathLength + addedLength, metric.length);
}
double _updateRemainingLength({
required double delta,
required double end,
required double availableEnd,
required double initialLength,
}) {
return (delta > 0 && availableEnd == end) ? delta : initialLength;
}
}
Run Code Online (Sandbox Code Playgroud)
mal*_*aki 13
// garis putus putus
Row(
children: List.generate(150~/10, (index) => Expanded(
child: Container(
color: index%2==0?Colors.transparent
:Colors.grey,
height: 2,
),
)),
),
Run Code Online (Sandbox Code Playgroud)
mak*_*imr 12
作为一种解决方法,您可以执行以下操作
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,
);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它 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),
],
),
),
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 10
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;
}
Run Code Online (Sandbox Code Playgroud)
并且使用 CustomPaint 小部件:
CustomPaint(painter: LineDashedPainter())
Run Code Online (Sandbox Code Playgroud)
Lê *_*Huy 10
我已经编写了flutter_dash库来绘制那个破折号。只有一行,你应该有一个破折号:D
Dash(length: 200, dashColor: Colors.red)
Run Code Online (Sandbox Code Playgroud)
试一试!
感谢marksimr的回答,这里是垂直和水平虚线的代码。
水平使用:
DashLineView(
fillRate: 0.7,
),
Run Code Online (Sandbox Code Playgroud)
垂直用途:
DashLineView(
fillRate: 0.7,
direction: Axis.vertical,
),
Run Code Online (Sandbox Code Playgroud)
完整代码:
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,
);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4570 次 |
| 最近记录: |