import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
class ThirdPage extends StatefulWidget {
const ThirdPage({Key? key}) : super(key: key);
@override
State<ThirdPage> createState() => _ThirdPageState();
}
class _ThirdPageState extends State<ThirdPage> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '自定义弹窗表格应用',
theme: ThemeData(primarySwatch: Colors.blue),
home: ProjectListPage(),
);
}
}
class TableRowData {
final String fixedContent;
String editableContent;
final String presetContent;
TableRowData({
required this.fixedContent,
this.editableContent = "",
required this.presetContent,
});
Map<String, dynamic> toJson() => {
'fixedContent': fixedContent,
'editableContent': editableContent,
'presetContent': presetContent,
};
factory TableRowData.fromJson(Map<String, dynamic> json) => TableRowData(
fixedContent: json['fixedContent'],
editableContent: json['editableContent'],
presetContent: json['presetContent'],
);
}
class Project {
String name;
List<TableRowData> rows;
Project({required this.name, required this.rows});
Map<String, dynamic> toJson() => {
'name': name,
'rows': rows.map((row) => row.toJson()).toList(),
};
factory Project.fromJson(Map<String, dynamic> json) => Project(
name: json['name'],
rows: (json['rows'] as List)
.map((row) => TableRowData.fromJson(row))
.toList(),
);
}
class ProjectListPage extends StatefulWidget {
@override
_ProjectListPageState createState() => _ProjectListPageState();
}
class _ProjectListPageState extends State<ProjectListPage> {
List<Project> projects = [];
@override
void initState() {
super.initState();
_loadProjects();
}
// 加载保存的项目
Future<void> _loadProjects() async {
final prefs = await SharedPreferences.getInstance();
final String? projectsJson = prefs.getString('projects');
if (projectsJson != null) {
final List<dynamic> jsonList = json.decode(projectsJson);
setState(() {
projects = jsonList.map((json) => Project.fromJson(json)).toList();
});
}
}
// 保存项目列表
Future<void> _saveProjects() async {
final prefs = await SharedPreferences.getInstance();
final List<Map<String, dynamic>> projectsJson =
projects.map((project) => project.toJson()).toList();
await prefs.setString('projects', json.encode(projectsJson));
}
// 获取第一列固定内容
String _getFixedContent(int rowIndex) {
final contents = [
"固定内容行 1",
"固定内容行 2",
"固定内容行 3",
"固定内容行 4",
"固定内容行 5",
"固定内容行 6",
"固定内容行 7",
"固定内容行 8",
"固定内容行 9"
];
return contents[rowIndex];
}
// 获取预设弹窗内容
String _getPresetContent(int rowIndex) {
final contents = [
"安全警告:参数超出安全范围\n建议值:25-50",
"操作确认:此操作不可撤",
"系统通知:数据已成功保存\n位",
"提醒:请完成所有必填字段\n缺失字段I",
"错误:输入格式不正确\n请输入数",
"性能提示:优化算法复杂度",
"警告:资源使用超过阈值\n当",
"确认:是否提交当前修改?\n",
"成功:操作执行完成\n"
];
return contents[rowIndex];
}
// 添加新项目
void _addNewProject() {
List<TableRowData> rows = List.generate(
9,
(index) => TableRowData(
fixedContent: _getFixedContent(index),
presetContent: _getPresetContent(index),
));
setState(() {
projects.add(Project(
name: '',
rows: rows,
));
_saveProjects();
});
}
// 删除项目
void _deleteProject(int index) {
setState(() {
projects.removeAt(index);
_saveProjects();
});
}
// 导航到表格详情页
void _navigateToTableDetail(BuildContext context, Project project) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TableDetailPage(project: project),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("CBT",
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontFamily: 'Comic Sans MS',
fontSize: 20.0,
fontWeight: FontWeight.w500,
)),
centerTitle: true,
backgroundColor: Colors.transparent,
elevation: 0,
surfaceTintColor: Colors.transparent,
flexibleSpace: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/background.jpg'), // 图片路径
fit: BoxFit.cover, // 覆盖整个区域
),
),
),
),
body: projects.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.table_chart, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text('暂无表格项目', style: TextStyle(fontSize: 18)),
SizedBox(height: 8),
Text('点击右下角按钮创建新项目'),
],
),
)
: ListView.builder(
padding: EdgeInsets.all(8),
itemCount: projects.length,
itemBuilder: (context, index) {
return Card(
margin: EdgeInsets.only(bottom: 12),
elevation: 0,
child: ListTile(
contentPadding:
EdgeInsets.symmetric(horizontal: 16, vertical: 20),
minVerticalPadding: 24, // 设置最小垂直间距
title: TextField(
controller:
TextEditingController(text: projects[index].name),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.zero,
hintText: '输入项目名称',
),
style: TextStyle(fontSize: 18),
onChanged: (value) {
setState(() {
projects[index].name = value;
_saveProjects();
});
},
),
trailing: Row(
mainAxisSize: MainAxisSize.min, // 让Row尽量小
children: [
IconButton(
icon: Icon(Icons.edit, color: Colors.blue), // 编辑图标,蓝色
onPressed: () => _navigateToTableDetail(
context, projects[index]), // 编辑项目的函数,需要用户自己实现
),
IconButton(
icon:
Icon(Icons.delete, color: Colors.red), // 删除图标,红色
onPressed: () => _deleteProject(index),
),
],
),
onTap: () =>
_navigateToTableDetail(context, projects[index]),
),
);
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: _addNewProject,
tooltip: '添加新项目',
),
);
}
}
class TableDetailPage extends StatefulWidget {
final Project project;
TableDetailPage({required this.project});
@override
_TableDetailPageState createState() => _TableDetailPageState();
}
class _TableDetailPageState extends State<TableDetailPage> {
late Project _project;
bool _isSaving = false;
@override
void initState() {
super.initState();
_project = widget.project;
}
Future<void> _saveProject() async {
setState(() => _isSaving = true);
try {
final prefs = await SharedPreferences.getInstance();
final String? projectsJson = prefs.getString('projects');
List<Project> projects = [];
if (projectsJson != null) {
List<dynamic> jsonList = json.decode(projectsJson);
projects = jsonList.map((json) => Project.fromJson(json)).toList();
}
// 查找当前项目在列表中的位置
int index = projects.indexWhere((p) => p.name == _project.name);
if (index != -1) {
projects[index] = _project;
} else {
projects.add(_project);
}
// 保存更新后的项目列表
final String updatedJson =
json.encode(projects.map((p) => p.toJson()).toList());
await prefs.setString('projects', updatedJson);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('保存成功!'),
backgroundColor: Colors.green,
duration: Duration(seconds: 2),
));
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('保存失败: $e'),
backgroundColor: Colors.red,
));
} finally {
setState(() => _isSaving = false);
}
}
/*bool _validateData() {
// 实现数据验证逻辑
return true;
}
// 保存项目数据
Future<void> _saveProject() async {
final prefs = await SharedPreferences.getInstance();
final List<Project> projects = [];
// 加载现有项目
Future<void> _loadProjects() async {
final String? projectsJson = prefs.getString('projects');
if (projectsJson != null) {
final List<dynamic> jsonList = json.decode(projectsJson);
projects
.addAll(jsonList.map((json) => Project.fromJson(json)).toList());
}
}
// 更新当前项目
final index = projects.indexWhere((p) => p.name == _project.name);
if (index != -1) {
projects[index] = _project;
}
// 保存更新后的项目列表
Future<void> _saveProjects() async {
final List<Map<String, dynamic>> projectsJson =
projects.map((project) => project.toJson()).toList();
await prefs.setString('projects', json.encode(projectsJson));
}
}
// 编辑第二列内容
void _editSecondColumn(BuildContext context, int rowIndex) {
String currentValue = _project.rows[rowIndex].editableContent;
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('编辑内容'),
content: TextField(
autofocus: true,
controller: TextEditingController(text: currentValue),
onChanged: (value) => currentValue = value,
),
actions: [
TextButton(
child: Text('取消'),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text('保存'),
onPressed: () {
setState(() {
_project.rows[rowIndex].editableContent = currentValue;
_saveProject();
});
Navigator.pop(context);
},
),
],
),
);
}*/
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_project.name),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ThirdPage()), // 目标页面
);
},
),
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(16),
child: Table(
border: TableBorder.all(color: Colors.grey[300]!),
columnWidths: {
0: FixedColumnWidth(80),
1: FixedColumnWidth(240),
2: FixedColumnWidth(80),
},
children: [
// 表头
TableRow(
decoration: BoxDecoration(color: Colors.transparent),
children: [
TableCell(
child: Padding(
padding: EdgeInsets.all(12),
child: Text('固定列',
style: TextStyle(fontWeight: FontWeight.bold)),
)),
TableCell(
child: Padding(
padding: EdgeInsets.all(12),
child: Text('可编辑列',
style: TextStyle(fontWeight: FontWeight.bold)),
)),
TableCell(
child: Padding(
padding: EdgeInsets.all(12),
child: Text('操作',
style: TextStyle(fontWeight: FontWeight.bold)),
)),
],
),
// 表格内容(9行)
...List.generate(9, (rowIndex) {
return TableRow(
decoration: BoxDecoration(
color: Colors.transparent,
),
children: [
// 第一列:固定内容,不可修改
TableCell(
child: Padding(
padding: EdgeInsets.all(12),
child: Text(
_project.rows[rowIndex].fixedContent,
style: TextStyle(color: Colors.grey[700]),
),
),
),
// 第二列:可编辑内容,点击编辑
TableCell(
child: Padding(
padding: EdgeInsets.all(8),
child: TextField(
controller:
TextEditingController.fromValue(TextEditingValue(
text: _project.rows[rowIndex].editableContent,
selection: TextSelection.collapsed(
offset: _project.rows[rowIndex].editableContent
.length, // 光标在末尾
),
)),
onChanged: (value) {
setState(() {
_project.rows[rowIndex].editableContent = value;
});
},
textDirection: TextDirection.ltr,
maxLines: null, // 关键参数:允许无限多行(自动扩展)
minLines: 2, // 初始最小显示行数
keyboardType: TextInputType.multiline, // 启用多行键盘
textInputAction: TextInputAction.newline, // 回车键换行
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 8),
hintText: '输入内容',
border: InputBorder.none,
),
),
),
),
// 第三列:按钮,弹出预设内容
TableCell(
child: Padding(
padding: EdgeInsets.all(8),
child: IconButton(
icon: Icon(Icons.info_outline, size: 20),
color: Colors.blue,
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('系统信息'),
content: SingleChildScrollView(
child: Text(
_project.rows[rowIndex].presetContent,
style: TextStyle(fontSize: 16),
),
),
actions: [
TextButton(
child: Text('关闭'),
onPressed: () => Navigator.pop(context),
),
],
),
);
},
),
),
),
],
);
}),
],
),
),
),
// 添加底部保存按钮
floatingActionButton: FloatingActionButton.extended(
icon: Icon(Icons.save),
label: Text(_isSaving ? '保存中...' : '保存更改'),
onPressed: _isSaving ? null : _saveProject,
backgroundColor: _isSaving ? Colors.grey : Colors.blue,
),
);
}
}在列表页的appbar加一个返回键