起因, 目的:
来源就是客户需求。 从个人角度来说,我讨厌 flutter, 和 java 一样, 都是 臃肿,繁琐,死板.
1. 过程:
根据用户的屏幕尺寸,把子元素大小, 字体的大小,都设置为百分比,无需插件。
2. 有个报错: 无法打开包括文件: "atlstr.h": No such file...
- 我先换成 Chrome 浏览器运行。成功。
- 然后,把代码复制到另一个新项目,运行,成功。
- 所以,原因是,客户提供的配置环境与我电脑上的环境不匹配, 而不是代码有问题! 也不是我的环境有问题。
3. 代码: tree_1.dart
dart
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyApp())); // Wrap MyApp with MaterialApp
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class NodeTemplate {
int id = 0;
int value = 0;
bool solid = false;
Color color = Colors.grey;
NodeTemplate();
}
// -------------------- 从这里开始 !!!! ----------------------------
class _MyAppState extends State<MyApp> {
// This list holds the color of each box, initially all are grey.
int nodeValue = 100;
List<Color> boxColors = List<Color>.filled(15, Colors.grey);
List<NodeTemplate> treeNodes =
List<NodeTemplate>.generate(15, (_) => NodeTemplate());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Draggable Blue Box'),
),
body: Column(
children: [
// Binary tree structure
Expanded(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Level 1 - 1 box 11111111111111111111111111111111111111111111111111111111
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildDragTarget(0),
],
),
SizedBox(height: 16.0), // For spacing between levels
// Level 2 - 2 boxes 22222222222222222222222222222222222222222222222222222222
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildDragTarget(1),
SizedBox(width: 100),
buildDragTarget(2),
],
),
SizedBox(height: 16.0), // For spacing between levels
// Level 3 - 4 boxes 333333333333333333333333333333333333333333333333333333
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildDragTarget(3),
SizedBox(width: 50),
buildDragTarget(4),
SizedBox(width: 50),
buildDragTarget(5),
SizedBox(width: 50),
buildDragTarget(6),
],
),
SizedBox(height: 16.0), // For spacing between levels
// Level 4 - 8 boxes 44444444444444444444444444444444444444444444444444
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildDragTarget(7),
buildDragTarget(8),
buildDragTarget(9),
buildDragTarget(10),
buildDragTarget(11),
buildDragTarget(12),
buildDragTarget(13),
buildDragTarget(14),
],
),
],
),
),
),
// Draggable blue box at the bottom
Draggable<int>(
data: nodeValue,
feedback: Container(
width: 50.0,
height: 50.0,
color: Colors.blue.withOpacity(0.7),
child: Center(child: Text(nodeValue.toString())),
),
childWhenDragging: Container(
width: 50.0,
height: 50.0,
color: Colors.blue.withOpacity(0.3),
),
child: Container(
width: 50.0,
height: 50.0,
color: Colors.blue,
child: Center(child: Text(nodeValue.toString())),
),
),
SizedBox(height: 30),
],
),
// Use the built-in floatingActionButton property
floatingActionButton: FloatingActionButton(
onPressed: () {
_showInputDialog(context); // Show the dialog to enter value
},
backgroundColor: Colors.blue,
child: Icon(Icons.add),
),
);
}
void _showInputDialog(BuildContext context) {
TextEditingController controller = TextEditingController();
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Enter value for the Node'),
content: TextField(
controller: controller,
keyboardType: TextInputType.number,
decoration: InputDecoration(hintText: "Enter value"),
),
actions: [
TextButton(
onPressed: () {
setState(() {
nodeValue = int.tryParse(controller.text) ??
0; // Parse input or default to 0
});
Navigator.of(context).pop(); // Close the dialog
},
child: Text('Submit'),
),
],
);
},
);
}
// Function to build a DragTarget for the grey boxes
Widget buildDragTarget(int index) {
return GestureDetector(
onLongPress: () {
setState(() {
treeNodes[index].id = index;
treeNodes[index].value = 0;
treeNodes[index].color = Colors.grey;
treeNodes[index].solid = false;
});
},
child: DragTarget<int>(
onAccept: (data) {
setState(() {
treeNodes[index].color =
Colors.blue; // Change color when blue box is dropped
treeNodes[index].value = data;
treeNodes[index].solid = true;
});
},
builder: (context, candidateData, rejectedData) {
// 获取屏幕的宽度和高度
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
// 根据屏幕大小调整宽度和高度,可以设置为屏幕宽度的百分比
double containerWidth = screenWidth * 0.08; // 比如宽度占屏幕宽度的 10%
double containerHeight = screenHeight * 0.1; // 比如高度占屏幕高度的 10%
// 动态调整 字体大小
double fontSize = 500 * 0.05; // 根据屏幕宽度动态调整字体大小
return Container(
width: containerWidth, //50.0, 80.0
height: containerHeight, //100.0,
margin: EdgeInsets.symmetric(horizontal: 4.0),
decoration: BoxDecoration(
color: treeNodes[index].color, // Dynamic color based on state
shape: BoxShape.circle, // Makes the container a circle
),
//color: treeNodes[index].color, // Dynamic color based on state
child: Center(
child: Text(
treeNodes[index].value.toString(),
// style: TextStyle(fontSize: 10),
style: TextStyle(fontSize: fontSize),
),
),
);
},
),
);
}
}
效果图