使用的插件
graphview: ^1.2.0
效果图

优点
1.item可以自定义
2.当前页面无法全部展示时,可以进行拖拽查看
3.可以鼠标滚轮进行放大缩小
缺点
1.节点不能多对多进行链接
主要代码
代码中使用了自己的状态管理框架,可以直接去掉,使用stateflu 即可
import 'package:flutter/material.dart';
import 'package:graphview/GraphView.dart';
import 'package:ui_state/state_widget.dart';
import 'logic.dart';
import '../../../system/kit.dart';
class Tree extends StatelessWidget {
const Tree({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("班级组织架构"),
),
body: StateWidget(
logic: TreeLogic(context),
builder: (logic) => InteractiveViewer(
constrained: false,
boundaryMargin: const EdgeInsets.all(50),
minScale: 0.01,
maxScale: 5.6,
child: GraphView(
graph: logic.graph,
algorithm: BuchheimWalkerAlgorithm(
logic.builder1, TreeEdgeRenderer(logic.builder1)),
paint: Paint()
..color = Colors.green
..strokeWidth = 1
..style = PaintingStyle.stroke,
builder: (Node node) {
var a = node.key!.value as int?;
var nodes = logic.json['nodes']!;
var nodeValue = nodes.firstWhere((element) => element['id'] == a);
return rectangleWidget(nodeValue["label"] as Map);
},
),
),
),
);
}
}
Widget rectangleWidget(Map nodes) {
List<Map<String, String>> list = nodes["list"];
return InkWell(
onTap: () {},
child: Container(
padding: nodes["tag"] == "h"
? const EdgeInsets.fromLTRB(0, 5, 0, 5)
: const EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey.shade500),
color: Colors.white,
),
child: nodes["tag"] == "h"
? Row(
children: list
.map(
(e) => Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.blue.shade100, spreadRadius: 1),
],
),
child: Padding(
padding: const EdgeInsets.all(5),
child: Row(
children: [
kit.avatar(imageUrl: "${e["image"]}", size: 30),
Padding(
padding: const EdgeInsets.only(left: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("${e["name"]}"),
Text("${e["job"]}",style: TextStyle(color: Colors.grey.shade500,fontSize: 14),),
],
),
)
],
),
),
),
),
)
.toList(),
)
: Column(
children: [
Text("${nodes["group"]}"),
Column(
children: list
.map(
(e) => Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Container(
width: 150,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.blue.shade100,
spreadRadius: 1),
],
),
child: ListTile(
contentPadding:
const EdgeInsets.fromLTRB(5, 0, 0, 5),
leading: kit.avatar(
imageUrl: "${e["image"]}", size: 30),
title: Text(
"${e["name"]}",
),
subtitle: e.containsKey("job")
? Text(
"${e["job"]}",
overflow: TextOverflow.ellipsis,
)
: const SizedBox.shrink(),
),
),
),
)
.toList(),
)
],
),
),
);
}