一书闸、IntrinsicHeight
1.在最壞的情況下阿弃,這個(gè)渲染對(duì)象可能導(dǎo)致樹深度為 O(N2)
的時(shí)間復(fù)雜度擂涛。IntrinsicHeight
會(huì)觸發(fā) 渲染樹中其所有子樹節(jié)點(diǎn)
的 getMaxIntrinsicHeight
方法來(lái)獲取尺寸窄赋。
2.通過源碼可知:在父級(jí)約束是緊約束的情況下 IntrinsicHeight
是毫無(wú)作用
的被芳。
3.IntrinsicHeight
的功能實(shí)現(xiàn),就是通過為子級(jí)在高度上施加緊約束實(shí)現(xiàn)的樱拴。
二柠衍、時(shí)光軸
思路:左邊的直線和虛線圓點(diǎn)都是都是通過自定義Decoration實(shí)現(xiàn)的洋满,右邊的內(nèi)容可以自定義,我這邊就是放了個(gè)顏色塊珍坊。因?yàn)橛疫叺母叨炔欢ㄎ矗瑢?dǎo)致左邊的直線高度不定,這里采用IntrinsicHeight套在頂層阵漏,就可以讓左邊的widget跟隨右邊的高度變化驻民。
三、自定義Decoration
1.寫個(gè)類實(shí)現(xiàn)Decoration
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return DashBoxPainter(decoration: this);
}
2.他需要BoxPainter履怯,也需要實(shí)現(xiàn)一個(gè)類
///Offset 表示左上角的位置回还,configuration.size是可以拿到對(duì)應(yīng)的控件大小的
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
}
四、整體的代碼實(shí)現(xiàn)
import 'package:dash_painter/dash_painter.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class TimeLineNode extends StatelessWidget {
double contentHeight;
TimeLineNode({Key? key, required this.contentHeight}) : super(key: key);
final double marginTop = 10;
final double dashLineWidth = 20;
final double offset = 20 + 10;
final double lineWidth = 2;
final double circleRadius = 5;
@override
Widget build(BuildContext context) {
return IntrinsicHeight(
child: Row(
children: [
_buildDecoration(),
Expanded(
flex: 5,
child: Container(
color: Colors.red,
height: contentHeight,
)),
const Spacer(
flex: 2,
)
],
),
);
}
Widget _buildDecoration() {
return Container(
margin: const EdgeInsets.only(left: 20),
width: dashLineWidth,
///不用寫高叹洲,因?yàn)楦吒鶕?jù)布局最大顯示
decoration: DashDecoration(
circleColor: Colors.blueAccent,
lineColor: Colors.white,
circleRadius: circleRadius,
color: Colors.white,
circleOffset: Offset(lineWidth / 2, offset + 10 / 2)),
);
}
}
class DashDecoration extends Decoration {
final Color color;
final Color circleColor;
final Color lineColor;
final Offset circleOffset;
final double circleRadius;
const DashDecoration(
{required this.color,
required this.circleColor,
required this.lineColor,
required this.circleOffset,
required this.circleRadius});
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return DashBoxPainter(decoration: this);
}
}
class DashBoxPainter extends BoxPainter {
final DashDecoration decoration;
const DashBoxPainter({required this.decoration});
///Offset 表示左上角的位置柠硕,configuration.size是可以拿到對(duì)應(yīng)的控件大小的
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
canvas.save();
final Paint paint = Paint()..style = PaintingStyle.stroke;
final Path path = Path();
// canvas.drawCircle(offset, 5, Paint()..color = Colors.blue);
debugPrint("offset ${offset.dx} dy : ${offset.dy}");
///為什么上面canvas需要保存,這里的canvas有平移
canvas.translate(offset.dx, offset.dy);
// canvas.drawCircle(offset, 5, Paint()..color = Colors.yellow);
//繪制直線
canvas.drawLine(
Offset(-decoration.circleOffset.dx, -decoration.circleOffset.dy),
Offset(-decoration.circleOffset.dx, configuration.size!.height),
paint
..color = decoration.lineColor
..strokeWidth = 2);
//繪制虛線
path
..moveTo(0, decoration.circleOffset.dy)
..relativeLineTo(configuration.size!.width, 0);
const DashPainter(span:2,step:3).
paint(canvas, path, paint..color = decoration.color..strokeWidth =1);
//繪制圓點(diǎn)
final Paint paint2 = Paint()..color = Colors.white;
canvas.drawCircle(
Offset(decoration.circleOffset.dx, decoration.circleOffset.dy),
decoration.circleRadius,
paint2);
canvas.drawCircle(
Offset(decoration.circleOffset.dx, decoration.circleOffset.dy),
decoration.circleRadius * 0.6,
paint2..color = decoration.circleColor);
canvas.restore();
}
}
調(diào)用代碼
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
// home: OverlayPage(),
home: Scaffold(
backgroundColor: Colors.black,
body: Container(
margin: const EdgeInsets.only(top: 46),
child: Column(children : [
TimeLineNode(contentHeight:50),
const SizedBox(height: 10,),
TimeLineNode(contentHeight:100),
const SizedBox(height: 10,),
TimeLineNode(contentHeight:150),
]))),
);
}
}