// math_tools_app.dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; // 添加这行 import 'tools/cuo_wei_xiang_jian.dart'; import 'tools/binomial_distribution.dart'; import 'tools/hypergeometric_distribution.dart'; import 'tools/chi_square.dart'; import 'tools/regression.dart'; import 'tools/mixed_variance.dart'; import 'tools/histogram.dart'; import 'tools/symmetry.dart'; import 'tools/circle_equation.dart'; import 'tools/vector_normal.dart'; import 'tools/bisection_method.dart'; import 'tools/function_plotter.dart'; import 'tools/parametric_plotter.dart'; import 'tools/derivative_calculator.dart'; import 'tools/advanced_ide.dart'; import 'tools/convolution_calculator.dart'; import 'tools/statistical_charts.dart'; class MathToolsApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: '某人的小工具', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MainPage(), ); } } class MainPage extends StatefulWidget { @override _MainPageState createState() => _MainPageState(); } class _MainPageState extends State { // 定义渐变色列表 final List colorGradient = [ Color(0xFFff6b6b), // 红色 Color(0xFFffa726), // 橙色 Color(0xFFffee58), // 黄色 Color(0xFF66bb6a), // 绿色 Color(0xFF42a5f5), // 蓝色 ]; final List allTools = [ MathTool('错位相减法', FontAwesomeIcons.subscript, CuoWeiXiangJianPage()), MathTool('二项分布', FontAwesomeIcons.dice, BinomialDistributionPage()), // 改为骰子图标 MathTool('超几何分布', FontAwesomeIcons.chartPie, HypergeometricDistributionPage()), MathTool('卷积分布列', FontAwesomeIcons.layerGroup, ConvolutionCalculatorPage()), MathTool('卡方检验', FontAwesomeIcons.checkSquare, ChiSquarePage()), MathTool('线性回归', FontAwesomeIcons.chartLine, RegressionPage()), MathTool('混合方差', FontAwesomeIcons.balanceScale, MixedVariancePage()), MathTool('直方图统计', FontAwesomeIcons.chartBar, HistogramPage()), MathTool('统计图表', FontAwesomeIcons.chartArea, StatisticalChartsPage()), MathTool('对称变换', FontAwesomeIcons.exchangeAlt, SymmetryPage()), MathTool('圆的方程', FontAwesomeIcons.circle, CircleEquationPage()), MathTool('三点法向量', FontAwesomeIcons.cube, VectorNormalPage()), MathTool('二分法求根', FontAwesomeIcons.search, BisectionMethodPage()), MathTool('函数图像绘制', FontAwesomeIcons.projectDiagram, FunctionPlotterPage()), MathTool('参数方程绘图', FontAwesomeIcons.waveSquare, ParametricPlotterPage()), MathTool('导数计算器', FontAwesomeIcons.calculator, DerivativeCalculatorPage()), MathTool('高级', FontAwesomeIcons.code, AdvancedIdePage()), MathTool('关于', FontAwesomeIcons.infoCircle, AboutPage()), ]; List filteredTools = []; TextEditingController searchController = TextEditingController(); FocusNode searchFocusNode = FocusNode(); @override void initState() { super.initState(); filteredTools = List.from(allTools); searchController.addListener(_onSearchChanged); } @override void dispose() { searchController.dispose(); searchFocusNode.dispose(); super.dispose(); } void _onSearchChanged() { setState(() { if (searchController.text.isEmpty) { filteredTools = List.from(allTools); } else { filteredTools = allTools.where((tool) { return tool.name.toLowerCase().contains(searchController.text.toLowerCase()); }).toList(); } }); } void _clearSearch() { setState(() { searchController.clear(); filteredTools = List.from(allTools); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Row( children: [ Text('某人的小工具', style: TextStyle(color: Colors.black)), Expanded( child: Container( margin: EdgeInsets.only(left: 16), height: 40, child: TextField( controller: searchController, focusNode: searchFocusNode, decoration: InputDecoration( hintText: '搜索工具...', hintStyle: TextStyle(fontSize: 14), prefixIcon: Icon(Icons.search, size: 20, color: Colors.grey), suffixIcon: searchController.text.isNotEmpty ? IconButton( icon: Icon(Icons.clear, size: 20, color: Colors.grey), onPressed: _clearSearch, ) : null, contentPadding: EdgeInsets.symmetric(vertical: 8, horizontal: 12), filled: true, fillColor: Colors.grey[100], border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(20), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(20), borderSide: BorderSide(color: Colors.blue, width: 1), ), ), style: TextStyle(fontSize: 14), ), ), ), ], ), backgroundColor: Colors.white, elevation: 1, ), body: filteredTools.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ FaIcon(FontAwesomeIcons.search, size: 60, color: Colors.grey[400]), SizedBox(height: 16), Text( '没有找到相关工具', style: TextStyle( fontSize: 18, color: Colors.grey[600], ), ), SizedBox(height: 8), Text( '请尝试使用其他关键词搜索', style: TextStyle( fontSize: 14, color: Colors.grey[500], ), ), SizedBox(height: 20), ElevatedButton( onPressed: _clearSearch, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), ), child: Text('清空搜索', style: TextStyle(color: Colors.white)), ), ], ), ) : GridView.builder( padding: EdgeInsets.all(16), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 16, mainAxisSpacing: 16, childAspectRatio: 1.2, ), itemCount: filteredTools.length, itemBuilder: (context, index) { // 根据索引计算渐变色 final colorIndex = (index / filteredTools.length * (colorGradient.length - 1)).clamp(0, colorGradient.length - 1).toInt(); final nextColorIndex = (colorIndex + 1).clamp(0, colorGradient.length - 1); final progress = (index / filteredTools.length * (colorGradient.length - 1)) - colorIndex; final color = Color.lerp(colorGradient[colorIndex], colorGradient[nextColorIndex], progress)!; return _buildToolCard(filteredTools[index], color, context); }, ), ); } Widget _buildToolCard(MathTool tool, Color color, BuildContext context) { return Card( elevation: 4, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: InkWell( borderRadius: BorderRadius.circular(12), onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => tool.page), ); }, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.white, // 改为白色背景 ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ FaIcon(tool.icon, size: 40, color: color), SizedBox(height: 8), Text( tool.name, textAlign: TextAlign.center, style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: color, ), ), ], ), ), ), ); } } class MathTool { final String name; final IconData icon; final Widget page; MathTool(this.name, this.icon, this.page); } // 关于页面 class AboutPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('关于', style: TextStyle(color: Colors.black)), backgroundColor: Colors.white, elevation: 1, ), body: Padding( padding: EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( child: FaIcon( FontAwesomeIcons.calculator, size: 80, color: Colors.blue, ), ), SizedBox(height: 20), Center( child: Text( '某人的小工具', style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Colors.blue, ), ), ), SizedBox(height: 10), Center( child: Text( '版本 1.1.0', style: TextStyle( fontSize: 16, color: Colors.grey[600], ), ), ), SizedBox(height: 30), Text( '应用介绍', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), SizedBox(height: 10), Text( '某人的小工具是一款专为高中教师设计的验算工具,' '提供了多种实用的数学计算和统计工具,帮助您更轻松地解决数学问题。' '由于是个人使用,主打的就是能用就行。', style: TextStyle(fontSize: 16, height: 1.5), ), SizedBox(height: 20), Text( '功能特点', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), SizedBox(height: 10), Expanded( child: ListView( children: [ _buildFeatureItem('统计概率', '分布列计算、数字特征'), _buildFeatureItem('数列计算', '错位相减'), _buildFeatureItem('解析几何', '对称变换、圆的方程'), _buildFeatureItem('函数导数', '图像绘制、导数求解'), _buildFeatureItem('高级功能', '手动编程'), ], ), ), SizedBox(height: 20), Center( child: Column( children: [ Text( '个人使用,严禁传播', style: TextStyle( fontSize: 14, color: Colors.grey[600], ), textAlign: TextAlign.center, ), SizedBox(height: 8), // 邮箱复制按钮 InkWell( onTap: () { _copyToClipboard('nonvioce@qq.com', context); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: Colors.blue[50], borderRadius: BorderRadius.circular(20), border: Border.all(color: Colors.blue[200]!), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ FaIcon(FontAwesomeIcons.envelope, size: 16, color: Colors.blue[700]), SizedBox(width: 6), Text( '反馈邮箱:nonvioce@qq.com', style: TextStyle( fontSize: 14, color: Colors.blue[700], fontWeight: FontWeight.w500, ), ), SizedBox(width: 4), FaIcon(FontAwesomeIcons.copy, size: 14, color: Colors.blue[700]), ], ), ), ), SizedBox(height: 10), Text( '©保留一切权利', style: TextStyle( fontSize: 12, color: Colors.grey[600], fontStyle: FontStyle.italic, ), ), ], ), ), ], ), ), ); } Widget _buildFeatureItem(String title, String description) { return Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ FaIcon(FontAwesomeIcons.checkCircle, color: Colors.green, size: 20), SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, ), ), Text( description, style: TextStyle( fontSize: 14, color: Colors.grey[600], ), ), ], ), ), ], ), ); } // 复制到剪贴板的函数 void _copyToClipboard(String text, BuildContext context) { Clipboard.setData(ClipboardData(text: text)); // 显示复制成功的提示 ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('邮箱地址已复制到剪贴板'), duration: Duration(seconds: 2), behavior: SnackBarBehavior.floating, ), ); } }