浏览代码

merge xiong

zhaoyadi 3 年之前
父节点
当前提交
7b2591e670
共有 100 个文件被更改,包括 3838 次插入8 次删除
  1. 二进制
      example/assets/image_header.png
  2. 二进制
      example/assets/thinking_core/ability_bg1.png
  3. 二进制
      example/assets/thinking_core/ability_bg2.png
  4. 二进制
      example/assets/thinking_core/ability_bg3.png
  5. 二进制
      example/assets/thinking_core/ability_bg4.png
  6. 二进制
      example/assets/thinking_core/ability_bg5.png
  7. 二进制
      example/assets/thinking_core/ability_selection.png
  8. 二进制
      example/assets/thinking_core/back.png
  9. 二进制
      example/assets/thinking_core/back_white.png
  10. 二进制
      example/assets/thinking_core/calendar.png
  11. 二进制
      example/assets/thinking_core/camera.png
  12. 二进制
      example/assets/thinking_core/camera_close.png
  13. 二进制
      example/assets/thinking_core/class_icon.png
  14. 二进制
      example/assets/thinking_core/close_white.png
  15. 二进制
      example/assets/thinking_core/competency_phase_bg.png
  16. 二进制
      example/assets/thinking_core/comprehensive_capabilities_bg1.png
  17. 二进制
      example/assets/thinking_core/comprehensive_capabilities_bg2.png
  18. 二进制
      example/assets/thinking_core/comprehensive_capabilities_bg3.png
  19. 二进制
      example/assets/thinking_core/comprehensive_capabilities_bg4.png
  20. 二进制
      example/assets/thinking_core/comprehensive_evaluat_on_record.png
  21. 二进制
      example/assets/thinking_core/customer_dog.png
  22. 二进制
      example/assets/thinking_core/customer_wechat.png
  23. 二进制
      example/assets/thinking_core/dog.png
  24. 二进制
      example/assets/thinking_core/dog_report.png
  25. 二进制
      example/assets/thinking_core/gaming_activities_bg1.png
  26. 二进制
      example/assets/thinking_core/gaming_activities_bg2.png
  27. 二进制
      example/assets/thinking_core/gaming_activities_bg3.png
  28. 二进制
      example/assets/thinking_core/gaming_activities_bg4.png
  29. 二进制
      example/assets/thinking_core/level.png
  30. 二进制
      example/assets/thinking_core/lock.png
  31. 二进制
      example/assets/thinking_core/people.png
  32. 二进制
      example/assets/thinking_core/policy_support.png
  33. 二进制
      example/assets/thinking_core/record_bg.png
  34. 二进制
      example/assets/thinking_core/report_generation_bg.png
  35. 二进制
      example/assets/thinking_core/report_tab_bar_bg.png
  36. 二进制
      example/assets/thinking_core/right_icon.png
  37. 二进制
      example/assets/thinking_core/single_assessment_record.png
  38. 二进制
      example/assets/thinking_core/strategy_bg.png
  39. 二进制
      example/assets/thinking_core/time.png
  40. 二进制
      example/fonts/YouSheBiaoTiHei-2.ttf
  41. 1 0
      example/ios/Flutter/Debug.xcconfig
  42. 1 0
      example/ios/Flutter/Release.xcconfig
  43. 41 0
      example/ios/Podfile
  44. 18 5
      example/ios/Runner.xcodeproj/project.pbxproj
  45. 242 0
      example/lib/one_page.dart
  46. 64 0
      example/lib/page1.dart
  47. 41 0
      example/lib/text_page.dart
  48. 61 0
      example/lib/three_page.dart
  49. 110 0
      example/lib/two_page.dart
  50. 13 3
      example/pubspec.yaml
  51. 25 0
      lib/src/data/data_management.dart
  52. 7 0
      lib/src/model/ability_selection_target_model.dart
  53. 101 0
      lib/src/model/competency_assessment_phase_model.dart
  54. 71 0
      lib/src/model/comprehensive_capabilities_model.dart
  55. 237 0
      lib/src/page/competency_assessment_phase_page.dart
  56. 189 0
      lib/src/page/comprehensive_evaluation_report/comprehensive_evaluation_report_page.dart
  57. 193 0
      lib/src/page/estimate/prepare_to_submit_records.dart
  58. 382 0
      lib/src/page/evaluation_records_or_reports/evaluation_records_or_reports_page.dart
  59. 155 0
      lib/src/page/playroom/game_park_page.dart
  60. 160 0
      lib/src/page/playroom/history_page.dart
  61. 201 0
      lib/src/page/playroom/playroom_page.dart
  62. 86 0
      lib/src/view/SideSelectionBar/AbilityAssessmentPhase/a_a_p_side_selection_bar.dart
  63. 22 0
      lib/src/view/SideSelectionBar/AbilityAssessmentPhase/ability_assessment_phase_side_selection_bar.dart
  64. 12 0
      lib/src/view/SideSelectionBar/AbilityAssessmentPhase/ability_assessment_phase_side_selection_bar_factory.dart
  65. 80 0
      lib/src/view/SideSelectionBar/EvaluationRecordCard/e_r_c_side_selection_bar.dart
  66. 22 0
      lib/src/view/SideSelectionBar/EvaluationRecordCard/evaluation_record_card_side_selection_bar.dart
  67. 12 0
      lib/src/view/SideSelectionBar/EvaluationRecordCard/evaluation_record_card_side_selection_bar_factory.dart
  68. 6 0
      lib/src/view/SideSelectionBar/i_side_selection_bar.dart
  69. 6 0
      lib/src/view/SideSelectionBar/i_side_selection_bar_factory.dart
  70. 11 0
      lib/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame.dart
  71. 10 0
      lib/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame_color.dart
  72. 20 0
      lib/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame_factory.dart
  73. 110 0
      lib/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame_view.dart
  74. 6 0
      lib/src/view/bulletf_rame/abstract/i_bulletf_rame.dart
  75. 5 0
      lib/src/view/bulletf_rame/abstract/i_bulletf_rame_color.dart
  76. 21 0
      lib/src/view/bulletf_rame/abstract/i_bulletf_rame_factory.dart
  77. 11 0
      lib/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame.dart
  78. 10 0
      lib/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame_color.dart
  79. 20 0
      lib/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame_factory.dart
  80. 204 0
      lib/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame_view.dart
  81. 11 0
      lib/src/view/bulletf_rame/customer/customer_bulletf_rame.dart
  82. 10 0
      lib/src/view/bulletf_rame/customer/customer_verify_bulletf_rame_color.dart
  83. 20 0
      lib/src/view/bulletf_rame/customer/customer_verify_bulletf_rame_factory.dart
  84. 123 0
      lib/src/view/bulletf_rame/customer/customer_verify_bulletf_rame_view.dart
  85. 11 0
      lib/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame.dart
  86. 9 0
      lib/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame_color.dart
  87. 20 0
      lib/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame_factory.dart
  88. 129 0
      lib/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame_view.dart
  89. 11 0
      lib/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame.dart
  90. 9 0
      lib/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame_color.dart
  91. 20 0
      lib/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame_factory.dart
  92. 52 0
      lib/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame_view.dart
  93. 6 0
      lib/src/view/bulletf_rame/verify/commit_verify_bulletf_rame_view.dart
  94. 6 0
      lib/src/view/bulletf_rame/verify/exit_verify_bulletf_rame_view.dart
  95. 17 0
      lib/src/view/bulletf_rame/verify/verify_bulletf_rame.dart
  96. 10 0
      lib/src/view/bulletf_rame/verify/verify_bulletf_rame_color.dart
  97. 24 0
      lib/src/view/bulletf_rame/verify/verify_bulletf_rame_factory.dart
  98. 92 0
      lib/src/view/bulletf_rame/verify/verify_bulletf_rame_view.dart
  99. 166 0
      lib/src/view/degree_of_exploration_content_widget.dart
  100. 105 0
      lib/src/view/degree_of_exploration_widget.dart

二进制
example/assets/image_header.png


二进制
example/assets/thinking_core/ability_bg1.png


二进制
example/assets/thinking_core/ability_bg2.png


二进制
example/assets/thinking_core/ability_bg3.png


二进制
example/assets/thinking_core/ability_bg4.png


二进制
example/assets/thinking_core/ability_bg5.png


二进制
example/assets/thinking_core/ability_selection.png


二进制
example/assets/thinking_core/back.png


二进制
example/assets/thinking_core/back_white.png


二进制
example/assets/thinking_core/calendar.png


二进制
example/assets/thinking_core/camera.png


二进制
example/assets/thinking_core/camera_close.png


二进制
example/assets/thinking_core/class_icon.png


二进制
example/assets/thinking_core/close_white.png


二进制
example/assets/thinking_core/competency_phase_bg.png


二进制
example/assets/thinking_core/comprehensive_capabilities_bg1.png


二进制
example/assets/thinking_core/comprehensive_capabilities_bg2.png


二进制
example/assets/thinking_core/comprehensive_capabilities_bg3.png


二进制
example/assets/thinking_core/comprehensive_capabilities_bg4.png


二进制
example/assets/thinking_core/comprehensive_evaluat_on_record.png


二进制
example/assets/thinking_core/customer_dog.png


二进制
example/assets/thinking_core/customer_wechat.png


二进制
example/assets/thinking_core/dog.png


二进制
example/assets/thinking_core/dog_report.png


二进制
example/assets/thinking_core/gaming_activities_bg1.png


二进制
example/assets/thinking_core/gaming_activities_bg2.png


二进制
example/assets/thinking_core/gaming_activities_bg3.png


二进制
example/assets/thinking_core/gaming_activities_bg4.png


二进制
example/assets/thinking_core/level.png


二进制
example/assets/thinking_core/lock.png


二进制
example/assets/thinking_core/people.png


二进制
example/assets/thinking_core/policy_support.png


二进制
example/assets/thinking_core/record_bg.png


二进制
example/assets/thinking_core/report_generation_bg.png


二进制
example/assets/thinking_core/report_tab_bar_bg.png


二进制
example/assets/thinking_core/right_icon.png


二进制
example/assets/thinking_core/single_assessment_record.png


二进制
example/assets/thinking_core/strategy_bg.png


二进制
example/assets/thinking_core/time.png


二进制
example/fonts/YouSheBiaoTiHei-2.ttf


+ 1 - 0
example/ios/Flutter/Debug.xcconfig

@@ -1 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
 #include "Generated.xcconfig"

+ 1 - 0
example/ios/Flutter/Release.xcconfig

@@ -1 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
 #include "Generated.xcconfig"

+ 41 - 0
example/ios/Podfile

@@ -0,0 +1,41 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '9.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+  'Debug' => :debug,
+  'Profile' => :release,
+  'Release' => :release,
+}
+
+def flutter_root
+  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+  unless File.exist?(generated_xcode_build_settings_path)
+    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+  end
+
+  File.foreach(generated_xcode_build_settings_path) do |line|
+    matches = line.match(/FLUTTER_ROOT\=(.*)/)
+    return matches[1].strip if matches
+  end
+  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+  use_frameworks!
+  use_modular_headers!
+
+  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+end
+
+post_install do |installer|
+  installer.pods_project.targets.each do |target|
+    flutter_additional_ios_build_settings(target)
+  end
+end

+ 18 - 5
example/ios/Runner.xcodeproj/project.pbxproj

@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 46;
+	objectVersion = 50;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -288,9 +288,13 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				DEVELOPMENT_TEAM = FN58BLDZJA;
 				ENABLE_BITCODE = NO;
 				INFOPLIST_FILE = Runner/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
 				PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -399,7 +403,8 @@
 				MTL_ENABLE_DEBUG_INFO = NO;
 				SDKROOT = iphoneos;
 				SUPPORTED_PLATFORMS = iphoneos;
-				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
 				TARGETED_DEVICE_FAMILY = "1,2";
 				VALIDATE_PRODUCT = YES;
 			};
@@ -412,9 +417,13 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				DEVELOPMENT_TEAM = FN58BLDZJA;
 				ENABLE_BITCODE = NO;
 				INFOPLIST_FILE = Runner/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
 				PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -431,9 +440,13 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				DEVELOPMENT_TEAM = FN58BLDZJA;
 				ENABLE_BITCODE = NO;
 				INFOPLIST_FILE = Runner/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
 				PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

+ 242 - 0
example/lib/one_page.dart

@@ -0,0 +1,242 @@
+import 'dart:math';
+import 'dart:math' as math;
+import 'dart:ui' as ui;
+import 'dart:ui';
+import 'package:flutter/material.dart';
+
+class OnePage extends StatefulWidget {
+  @override
+  OnePageState createState() => new OnePageState();
+}
+
+class OnePageState extends State<OnePage> {
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      backgroundColor: Color(0xFF3B62EE),
+      appBar: AppBar(
+        title: Text(''),
+      ),
+      body: Center(
+        child: radarMapComponent(
+          ["观察能力", "迁移发散能力", "归纳总结能力", "分类比较能力", "描述记录能力", "质疑猜想能力"],
+          // ["观察能力", "迁移发散能力", "归纳总结能力", "分类比较能力",],
+
+          30.0,
+          18.0,
+          context: context,
+        ),
+      ),
+    );
+  }
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+  }
+}
+
+/// titlesList:外面的标题数组
+/// minRadius:最小圆的半径
+/// poorRadius:扩散圆的半径差
+Widget radarMapComponent(List titlesList, double minRadius, double poorRadius, {BuildContext context}) {
+  double maxRadius = minRadius + poorRadius * titlesList.length - 1;
+
+  return Container(
+    width: maxRadius*2 + 100,
+    height: maxRadius*2 + 100,
+    child: CustomPaint(size: Size(maxRadius*2 + 100, maxRadius*2 + 100), painter: TolyPainter(titlesList: titlesList, minRadius: minRadius, poorRadius: poorRadius, context: context)),
+  );
+}
+
+class TolyPainter extends CustomPainter {
+  final BuildContext context;
+  final List titlesList;
+  final double minRadius;
+  final double poorRadius;
+
+  TolyPainter({@required this.context, this.titlesList, this.minRadius, this.poorRadius});
+
+  @override
+  void paint(Canvas canvas, Size size) {
+    double maxRadius = minRadius + poorRadius * (titlesList.length - 1);
+
+    canvas.translate(size.width / 2, size.height / 2);
+
+
+    //虚线画笔
+    Paint dottedLinePaint = Paint()
+      ..style = PaintingStyle.stroke
+      ..color = Color(0xFFB9BEE6)
+      ..strokeWidth = 1;
+
+    Paint paint = Paint()
+      ..style = PaintingStyle.stroke
+      ..color = Color(0xFFE5E3FD)
+      ..strokeWidth = 1;
+
+    //多边形画笔
+    Paint polygonBrushesPaint = Paint()
+      ..style = PaintingStyle.fill
+      ..color = Color(0xFFF6A5AB).withOpacity(0.52)
+      ..strokeWidth = 1;
+
+    Paint polygonBrushesPaint1 = Paint()
+      ..style = PaintingStyle.stroke
+      ..color = Color(0xFFF6A5AB)
+      ..strokeWidth = 1;
+
+    Path polygonBrushesPath = Path();
+
+    //文字画笔
+    TextPainter _textPainter = new TextPainter(textAlign: TextAlign.left, textDirection: TextDirection.ltr);
+
+    final Path path = Path();
+    final dottedLinePath = Path();
+
+
+
+    //绘制文字
+    for (int i = 0; i < titlesList.length; i++) {
+      Size textSize = boundingTextSize(context, titlesList[i], TextStyle(color: Colors.white, fontSize: 9));
+      canvas.save(); //与restore配合使用保存当前画布
+      canvas.translate(0.0, -maxRadius -10); //平移画布画点于时钟的12点位置,+30为了调整数字与刻度的间隔
+      _textPainter.text = TextSpan(style: TextStyle(color: Colors.white, fontSize: 9), text: titlesList[i]);
+      canvas.rotate(-angleToRadian(360 / titlesList.length * i)); //保持画的文字竖直显示。
+      _textPainter.layout();
+
+      //
+
+      double radiu = 360 / titlesList.length * i;
+
+      if (radiu == 0 || radiu == 1) {
+        _textPainter.paint(canvas, Offset(-_textPainter.width / 2 , -_textPainter.height / 2 - 5));
+      }
+      else if(0 <  radiu && radiu < 180){
+        _textPainter.paint(canvas, Offset(0, -5));
+      }
+      else if(180 <  radiu && radiu < 360){
+        _textPainter.paint(canvas, Offset(-_textPainter.width, -5));
+      }
+      else{
+        _textPainter.paint(canvas, Offset(-_textPainter.width / 2, -_textPainter.height / 2 + 5));
+      }
+
+
+      canvas.restore(); //画布重置,恢复到控件中心
+      canvas.rotate(angleToRadian(360 / titlesList.length)); //画布旋转一个区间刻度,把文字和刻度对应起来
+    }
+
+
+
+
+    List<Offset> pointsList = [];
+
+    for (int i = 0; i < titlesList.length; i++) {
+      path.moveTo(0, 0);
+      dottedLinePath.moveTo(0, 0);
+      if (i < titlesList.length - 1) {
+        dottedLinePath.addOval(Rect.fromCircle(center: Offset.zero, radius: 30.0 + 18 * i));
+      }
+
+      double maxRadius = minRadius + poorRadius * titlesList.length;
+      double x = (30 + 18 * (titlesList.length - 1)) * cos(angleToRadian(360 / titlesList.length * (i + 1) - 90));
+      double y = (30 + 18 * (titlesList.length - 1)) * sin(angleToRadian(360 / titlesList.length * (i + 1) - 90));
+
+      path.lineTo(x, y);
+      pointsList.add(Offset(cos(angleToRadian(360 / titlesList.length * (i + 1) - 90)) * maxRadius * (i + 1 > titlesList.length - 1 ? titlesList.length - 2 : i + 1) / titlesList.length, sin(angleToRadian(360 / titlesList.length * (i + 1) - 90)) * maxRadius * (i + 1 > titlesList.length - 1 ? titlesList.length - 1 : i + 1) / titlesList.length));
+    }
+
+    polygonBrushesPath.addPolygon(pointsList, true);
+
+    canvas.drawPath(polygonBrushesPath, polygonBrushesPaint);
+
+    canvas.drawPath(polygonBrushesPath, polygonBrushesPaint1);
+
+    for (int i = 0; i < titlesList.length; i++) {
+      ParagraphBuilder pb = ParagraphBuilder(ParagraphStyle(
+        textAlign: TextAlign.left,
+        fontWeight: FontWeight.w600,
+        fontStyle: FontStyle.normal,
+        fontSize: 7,
+      ))
+        ..pushStyle(ui.TextStyle(color: Color(0xFFB9BEE6)))
+        ..addText((i * 2).toString());
+      ParagraphConstraints pc = ParagraphConstraints(width: 50);
+      Paragraph paragraph = pb.build()..layout(pc);
+      canvas.drawParagraph(paragraph, Offset((minRadius + poorRadius * i) * (11 + 13 * i) / (minRadius+ poorRadius * i), (minRadius + poorRadius * i) * (11 + 13 * i) / (minRadius + poorRadius * i)));
+    }
+
+    DashPainter(span: 4, step: 9, pointWidth: 10).paint(canvas, dottedLinePath, dottedLinePaint);
+    canvas.drawPath(path, paint);
+    canvas.drawCircle(Offset.zero, minRadius + 18 * (titlesList.length - 1), paint);
+
+    ParagraphBuilder pb = ParagraphBuilder(ParagraphStyle(
+      textAlign: TextAlign.left,
+      fontWeight: FontWeight.w600,
+      fontStyle: FontStyle.normal,
+      fontSize: 7,
+    ))
+      ..pushStyle(ui.TextStyle(color: Color(0xFFB9BEE6)))
+      ..addText((titlesList.length * 2).toString());
+    ParagraphConstraints pc = ParagraphConstraints(width: 50);
+    Paragraph paragraph = pb.build()..layout(pc);
+    canvas.drawParagraph(paragraph, Offset((minRadius + poorRadius * titlesList.length) * (11 + 13 * titlesList.length) / (minRadius + poorRadius * titlesList.length), (minRadius + poorRadius * titlesList.length) * (11 + 13 * titlesList.length) / (minRadius + poorRadius * titlesList.length)));
+  }
+
+  static Size boundingTextSize(BuildContext context, String text, TextStyle style, {int maxLines = 2 ^ 31, double maxWidth = double.infinity}) {
+    if (text == null || text.isEmpty) {
+      return Size.zero;
+    }
+    final TextPainter textPainter = TextPainter(textDirection: TextDirection.ltr, locale: Localizations.maybeLocaleOf(context), text: TextSpan(text: text, style: style), maxLines: maxLines)..layout(maxWidth: maxWidth);
+    return textPainter.size;
+  }
+
+  ///角度换算成弧度 参数[angle]为角度
+  static double angleToRadian(double angle) {
+    return angle * pi / 180;
+  }
+
+  @override
+  bool shouldRepaint(covariant TolyPainter oldDelegate) => false;
+}
+
+class DashPainter {
+  const DashPainter({
+    this.step = 2,
+    this.span = 2,
+    this.pointCount = 0,
+    this.pointWidth,
+  });
+
+  final double step; //实现的长度
+  final double span; //虚线的长度
+  final int pointCount; //点划线数
+  final double pointWidth; //点划线长
+
+  void paint(Canvas canvas, Path path, Paint paint) {
+    final PathMetrics pms = path.computeMetrics(); //为此路径创建一个PathMetrics对象,该对象可以描述有关路径轮廓的各种属性。
+    final double pointLineLength = pointWidth;
+    final double partLength = step + span * (pointCount + 1) + pointCount * pointLineLength;
+
+    pms.forEach((PathMetric pm) {
+      final int count = pm.length ~/ partLength;
+      for (int i = 0; i < count; i++) {
+        canvas.drawPath(
+          pm.extractPath(partLength * i, partLength * i + step),
+          paint,
+        );
+        for (int j = 1; j <= pointCount; j++) {
+          final start = partLength * i + step + span * j + pointLineLength * (j - 1);
+          canvas.drawPath(
+            pm.extractPath(start, start + pointLineLength),
+            paint,
+          );
+        }
+      }
+      final double tail = pm.length % partLength;
+      canvas.drawPath(pm.extractPath(pm.length - tail, pm.length), paint);
+    });
+  }
+}

+ 64 - 0
example/lib/page1.dart

@@ -0,0 +1,64 @@
+import 'dart:math' as math;
+
+import 'package:flutter/material.dart';
+
+class Page1 extends StatefulWidget {
+  @override
+  Page1State createState() => new Page1State();
+}
+
+class Page1State extends State<Page1> {
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      color: Colors.orange,
+      // width: double.infinity,
+      // width: 100,
+      alignment: Alignment.center,
+      child: CustomPaint(
+        // size: Size(200, 100),
+        painter: MyPainter(),
+      ),
+    );
+  }
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+  }
+}
+
+class MyPainter extends CustomPainter {
+  @override
+  void paint(Canvas canvas, Size size) {
+
+    final rect = Size(200, 50);
+    final smallAngle = 1;
+    final leftTopRadius = 4.0;
+    final leftBottomRadius = 4.0;
+    final rightTopRadius = 4.0;
+    final rightBottomRadius = 4.0;
+
+    final paint = Paint()
+      ..color = Colors.red
+      ..strokeWidth = 2
+      ..style = PaintingStyle.fill;
+
+
+
+
+    var bezierPath = Path();
+
+
+
+
+
+    canvas.drawPath(bezierPath, paint);
+  }
+
+  @override
+  bool shouldRepaint(covariant CustomPainter oldDelegate) {
+    // TODO: implement shouldRepaint
+    return true;
+  }
+}

+ 41 - 0
example/lib/text_page.dart

@@ -0,0 +1,41 @@
+import 'dart:io';
+
+import 'package:example/three_page.dart';
+import 'package:flutter/material.dart';
+
+class TestPage extends StatefulWidget {
+  @override
+  TestPageState createState() => new TestPageState();
+}
+
+class TestPageState extends State<TestPage> {
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text('1'),
+      ),
+      body: Container(
+        color: Colors.white,
+        child: Center(
+          child: ElevatedButton(
+            child: Text("点击"),
+            onPressed: () async{
+
+              Navigator.push(context, MaterialPageRoute(builder: (_){
+                return ThreePage();
+              }));
+            },
+          ),
+        ),
+      ),
+    );
+  }
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+  }
+
+}

+ 61 - 0
example/lib/three_page.dart

@@ -0,0 +1,61 @@
+import 'package:flutter/material.dart';
+// import 'package:luojigou_thinking_core/src/view/';
+
+import 'package:luojigou_thinking_core/src/view/bulletf_rame/abstract/i_bulletf_rame_factory.dart';
+import 'package:luojigou_thinking_core/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame_factory.dart';
+import 'package:luojigou_thinking_core/src/view/bulletf_rame/customer/customer_verify_bulletf_rame_factory.dart';
+import 'package:luojigou_thinking_core/src/view/bulletf_rame/verify/verify_bulletf_rame_factory.dart';
+import 'package:luojigou_thinking_core/src/data/data_management.dart';
+import 'package:luojigou_thinking_core/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame_factory.dart';
+import 'package:luojigou_thinking_core/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame_factory.dart';
+import 'package:luojigou_thinking_core/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame_factory.dart';
+
+
+class ThreePage extends StatefulWidget {
+  @override
+  ThreePageState createState() => new ThreePageState();
+}
+
+class ThreePageState extends State<ThreePage> {
+  IBulletfRameFactory _iBulletfRameFactory;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    // _iBulletfRameFactory = PolicySupportBulletfRameFactory();
+    // _iBulletfRameFactory = CustomerBulletfRameFactory();
+    // _iBulletfRameFactory = ReportGenerationBulletfRameFactory();
+    // _iBulletfRameFactory = AlbumSelectionBulletfRameFactory();
+    _iBulletfRameFactory = AbilitySelectionBulletfRameFactory();
+    // _iBulletfRameFactory = VerifyBulletfRameFactory(VerifyType.Commit);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text('2'),
+      ),
+      body: Container(
+        color: Colors.white,
+        child: Center(
+          child: ElevatedButton(
+            child: Text("点击"),
+            onPressed: () {
+              Navigator.push(
+                  context,
+                  ActivateRouter(
+                    _iBulletfRameFactory.getBulletfRame().createBulletfRame(),
+                    _iBulletfRameFactory.getBulletfRameColor().getBulletfRameBarrierColor(),
+                  ));
+
+
+            },
+          ),
+        ),
+      ),
+    );
+  }
+}
+

+ 110 - 0
example/lib/two_page.dart

@@ -0,0 +1,110 @@
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar_factory.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/EvaluationRecordCard/evaluation_record_card_side_selection_bar_factory.dart';
+import 'package:luojigou_thinking_core/src/model/comprehensive_capabilities_model.dart';
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+
+class TwoPage extends StatefulWidget {
+  @override
+  TwoPageState createState() => new TwoPageState();
+}
+
+class TwoPageState extends State<TwoPage> {
+  List<AbilitySelectionTargetModel> dataList = [
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "思维能力与逻辑思考能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "科学能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "探索能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "观察能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "冲突能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "沟通能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "理解能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "学习能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "视听能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "坚持能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "专注能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "练习能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+  ];
+
+
+  ValueNotifier<int> _notifier;
+
+  ISideSelectionBarFactory _iSideSelectionBarFactory;
+  ISideSelectionBar _iSideSelectionBar;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _notifier = ValueNotifier(1);
+    _notifier.addListener(() {
+      print("切换卡片Index");
+      print(_notifier.value);
+    });
+
+    _iSideSelectionBarFactory = EvaluationRecordCardSideSelectionBarFactory();
+    // _iSideSelectionBarFactory = AbilityAssessmentPhaseSideSelectionBarFactory();
+    _iSideSelectionBar = _iSideSelectionBarFactory.getSideSelectionBar(dataList, (selectIndex) {
+      print(selectIndex);
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      backgroundColor: Color(0xFFD9E7FF),
+      body: Center(
+        child: _iSideSelectionBar.getSideSelectionBar(),
+      ),
+    );
+  }
+}
+

+ 13 - 3
example/pubspec.yaml

@@ -4,15 +4,16 @@ publish_to: 'none'
 version: 1.0.0+1
 
 environment:
-  sdk: ">=2.14.0 <3.0.0"
-  flutter: ">=2.5.0 <3.0.0"
+  sdk: ">=2.7.0 <3.0.0"
+#  flutter: ">=2.5.0 <3.0.0"
 
 dependencies:
   flutter:
     sdk: flutter
 
   luojigou_thinking_core:
-    path: ../
+    path: ../../luojigou_thinking_core
+
 
 dev_dependencies:
   flutter_lints: ^1.0.0
@@ -20,3 +21,12 @@ dev_dependencies:
 flutter:
   uses-material-design: true
 
+  assets:
+    - assets/
+    - assets/thinking_core/
+
+  fonts:
+    - family: YouSheBiaoTiHei
+      fonts:
+        - asset: fonts/YouSheBiaoTiHei-2.ttf
+          style: italic

+ 25 - 0
lib/src/data/data_management.dart

@@ -0,0 +1,25 @@
+/// 评估记录/报告底部视图
+enum AssessFooterViewType {
+  EvaluationRecordsFirst, //评估记录-->《开始批量评估》
+  EvaluationRecordsAgain, //评估记录-->《继续上次评估》
+  EvaluationReportAgain //评估报告-->《再次批量评估》
+}
+
+//学生信息Cell中的AccessoryView
+enum AssessAccessoryViewType {
+  Over, //已评估
+  Stay, //待评估
+  Send //评估报告-->发送给加载
+}
+
+enum ToggleState{
+  GamePark, //游戏乐园
+  History, //历史记录
+}
+
+//确认弹框类型
+enum VerifyType{
+  Commit, //提交
+  Exit, //退出
+}
+

+ 7 - 0
lib/src/model/ability_selection_target_model.dart

@@ -0,0 +1,7 @@
+//能力选择器目标接口
+mixin AbilitySelectionTargetModel{
+  String get getDomainAbilityName;
+  set setDomainAbilityName(String value);
+  bool get getIsSelected;
+  set setIsSelected(bool value);
+}

+ 101 - 0
lib/src/model/competency_assessment_phase_model.dart

@@ -0,0 +1,101 @@
+//能力评测阶段
+import 'ability_selection_target_model.dart';
+
+class CompetencyAssessmentPhaseModel implements AbilitySelectionTargetModel{
+  String? domainAbilityId;
+  String? domainAbilityName;
+  int? assess;
+  List<DegreeList>? list;
+  bool? isSelected;
+
+  CompetencyAssessmentPhaseModel(
+      {this.domainAbilityId, this.domainAbilityName, this.assess, this.list, this.isSelected});
+
+  CompetencyAssessmentPhaseModel.fromJson(Map<String, dynamic> json) {
+    domainAbilityId = json['domainAbilityId'];
+    domainAbilityName = json['domainAbilityName'];
+    assess = json['assess'];
+    isSelected = json['isSelected'];
+    if (json['list'] != null) {
+      list = <DegreeList>[];
+      json['list'].forEach((v) {
+        list!.add(new DegreeList.fromJson(v));
+      });
+    }
+  }
+
+  Map<String, dynamic> toJson() {
+    final Map<String, dynamic> data = new Map<String, dynamic>();
+    data['domainAbilityId'] = this.domainAbilityId;
+    data['domainAbilityName'] = this.domainAbilityName;
+    data['assess'] = this.assess;
+    data['isSelected'] = this.isSelected;
+    if (this.list != null) {
+      data['list'] = this.list!.map((v) => v.toJson()).toList();
+    }
+    return data;
+  }
+
+  String get getDomainAbilityName =>this.domainAbilityName!;
+  set setDomainAbilityName(String value){
+    this.domainAbilityName = value;
+  }
+  bool get getIsSelected => this.isSelected!;
+  set setIsSelected(bool value){
+    this.isSelected = value;
+  }
+
+}
+
+//早中后期
+class DegreeList {
+  String? abilityId;
+  String? abilityName;
+  List<LevelList>? list;
+
+  DegreeList({this.abilityId, this.abilityName, this.list});
+
+  DegreeList.fromJson(Map<String, dynamic> json) {
+    abilityId = json['abilityId'];
+    abilityName = json['abilityName'];
+    if (json['list'] != null) {
+      list = <LevelList>[];
+      json['list'].forEach((v) {
+        list!.add(new LevelList.fromJson(v));
+      });
+    }
+  }
+
+  Map<String, dynamic> toJson() {
+    final Map<String, dynamic> data = new Map<String, dynamic>();
+    data['abilityId'] = this.abilityId;
+    data['abilityName'] = this.abilityName;
+    if (this.list != null) {
+      data['list'] = this.list!.map((v) => v.toJson()).toList();
+    }
+    return data;
+  }
+}
+
+//能力程度
+class LevelList {
+  String? abilityLevelId;
+  String? abilityLevelName;
+  int? number;
+
+  LevelList({this.abilityLevelId, this.abilityLevelName, this.number});
+
+  LevelList.fromJson(Map<String, dynamic> json) {
+    abilityLevelId = json['abilityLevelId'];
+    abilityLevelName = json['abilityLevelName'];
+    number = json['number'];
+  }
+
+  Map<String, dynamic> toJson() {
+    final Map<String, dynamic> data = new Map<String, dynamic>();
+    data['abilityLevelId'] = this.abilityLevelId;
+    data['abilityLevelName'] = this.abilityLevelName;
+    data['number'] = this.number;
+    return data;
+  }
+}

+ 71 - 0
lib/src/model/comprehensive_capabilities_model.dart

@@ -0,0 +1,71 @@
+//综合区能力列表
+import 'ability_selection_target_model.dart';
+
+class ComprehensiveCapabilitiesModel implements AbilitySelectionTargetModel{
+  String? domainAbilityName;
+  String? id;
+  String? gameTypeId;
+  String? gameDistrictId;
+  String? domainId;
+  String? domainAbilityId;
+  String? valuationDate;
+  List<String>? relationIds;
+  String? createTime;
+  String? updateTime;
+  bool? isSelected;
+
+  ComprehensiveCapabilitiesModel({
+    this.domainAbilityName,
+    this.id,
+    this.gameTypeId,
+    this.gameDistrictId,
+    this.domainId,
+    this.domainAbilityId,
+    this.valuationDate,
+    this.relationIds,
+    this.createTime,
+    this.updateTime,
+    this.isSelected,
+  });
+
+  ComprehensiveCapabilitiesModel.fromJson(Map<String, dynamic> json) {
+    domainAbilityName = json['domainAbilityName'];
+    id = json['id'];
+    gameTypeId = json['gameTypeId'];
+    gameDistrictId = json['gameDistrictId'];
+    domainId = json['domainId'];
+    domainAbilityId = json['domainAbilityId'];
+    valuationDate = json['valuationDate'];
+    relationIds = json['relationIds'].cast<String>();
+    createTime = json['createTime'];
+    updateTime = json['updateTime'];
+    isSelected = json['isSelected'];
+  }
+
+  Map<String, dynamic> toJson() {
+    final Map<String, dynamic> data = new Map<String, dynamic>();
+    data['domainAbilityName'] = this.domainAbilityName;
+    data['id'] = this.id;
+    data['gameTypeId'] = this.gameTypeId;
+    data['gameDistrictId'] = this.gameDistrictId;
+    data['domainId'] = this.domainId;
+    data['domainAbilityId'] = this.domainAbilityId;
+    data['valuationDate'] = this.valuationDate;
+    data['relationIds'] = this.relationIds;
+    data['createTime'] = this.createTime;
+    data['updateTime'] = this.updateTime;
+    data['isSelected'] = this.isSelected;
+    return data;
+  }
+
+  String get getDomainAbilityName =>this.domainAbilityName!;
+  set setDomainAbilityName(String value){
+    this.domainAbilityName = value;
+  }
+  bool get getIsSelected => this.isSelected!;
+  set setIsSelected(bool value){
+    this.isSelected = value;
+  }
+
+
+}

+ 237 - 0
lib/src/page/competency_assessment_phase_page.dart

@@ -0,0 +1,237 @@
+import 'package:flutter/material.dart';
+import 'dart:ui';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar_factory.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/AbilityAssessmentPhase/ability_assessment_phase_side_selection_bar_factory.dart';
+import 'package:luojigou_thinking_core/src/model/competency_assessment_phase_model.dart';
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+
+/// 能力评估阶段
+class CompetencyAssessmentPhasePage extends StatefulWidget {
+  @override
+  CompetencyAssessmentPhasePageState createState() => new CompetencyAssessmentPhasePageState();
+}
+
+class CompetencyAssessmentPhasePageState extends State<CompetencyAssessmentPhasePage> {
+  List<AbilitySelectionTargetModel> dataList = [
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "思维能力与逻辑思考能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "科学能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "探索能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "观察能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "冲突能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "沟通能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "理解能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "学习能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "视听能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "坚持能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "专注能力", "isSelected": false}),
+    CompetencyAssessmentPhaseModel.fromJson({"domainAbilityName": "练习能力", "isSelected": false}),
+  ];
+
+  late ValueNotifier<int> _notifier;
+
+  late ISideSelectionBarFactory _iSideSelectionBarFactory;
+  late ISideSelectionBar _iSideSelectionBar;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _notifier = ValueNotifier(1);
+    _notifier.addListener(() {
+      print("切换卡片Index");
+      print(_notifier.value);
+    });
+
+    _iSideSelectionBarFactory = AbilityAssessmentPhaseSideSelectionBarFactory();
+    _iSideSelectionBar = _iSideSelectionBarFactory.getSideSelectionBar(dataList, (selectIndex) {
+      print(selectIndex);
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      body: Container(
+        width: double.infinity,
+        height: double.infinity,
+        alignment: Alignment.topRight,
+        decoration: BoxDecoration(gradient: LinearGradient(colors: [Color(0xFFD5E3F8), Color(0xFFEAF5FF)], begin: Alignment(-1 + 0.88, -1 + 0.04), end: Alignment(0, 0))),
+        child: Stack(
+          children: [
+            Image.asset("assets/thinking_core/competency_phase_bg.png"),
+            Column(
+              children: [
+                AppNavBar(context),
+                Expanded(
+                  child: MediaQuery.removePadding(
+                    context: context,
+                    removeTop: true,
+                    child: Row(
+                      children: [
+                        Expanded(
+                          child: LeftView(),
+                        ),
+                        _iSideSelectionBar.getSideSelectionBar(),
+                      ],
+                    ),
+                  ),
+                )
+              ],
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Container LeftView() {
+    return Container(
+      margin: EdgeInsets.only(left: 18, top: 20, bottom: 64.5),
+      decoration: BoxDecoration(color: Color(0xFFFFFFFF), borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: Color(0x1A000000), offset: Offset(2, 0), blurRadius: 15, spreadRadius: 0)]),
+      child: Column(
+        children: [
+          SizedBox(height: 34),
+          Text(
+            "李启沃",
+            style: TextStyle(color: Colors.black, fontSize: 17, height: 24 / 17, fontWeight: FontWeight.w400),
+          ),
+          SizedBox(height: 3),
+          Text(
+            "(当前5项能力展示)",
+            style: TextStyle(color: Color(0xFF666666), fontSize: 13, height: 18.5 / 13),
+          ),
+          SizedBox(height: 14),
+          Expanded(child: DegreeScaleListView())
+        ],
+      ),
+    );
+  }
+
+  ListView DegreeScaleListView() {
+    return ListView.separated(
+        padding: EdgeInsets.only(bottom: 14),
+        itemCount: 9,
+        itemBuilder: (context, index) {
+          return Container(
+            width: double.infinity,
+            height: 116,
+            margin: EdgeInsets.only(left: 15, right: 18),
+            decoration:
+                BoxDecoration(color: Color(0xFFFFFFFF), borderRadius: BorderRadius.circular(15), border: Border.all(color: Color(0xFFA8CAFF), width: 1), boxShadow: [BoxShadow(color: Color(0xFFA8CAFF), offset: Offset(5, 0), blurRadius: 0, spreadRadius: 0)]),
+            child: Row(
+              children: [
+                SizedBox(width: 20),
+                Text(
+                  "探\n索\n程\n度",
+                  style: TextStyle(fontSize: 19, height: 24 / 19, color: Color(0xFF5F87F0), fontFamily: "YouSheBiaoTiHei"),
+                ),
+                SizedBox(width: 26.5),
+                Expanded(
+                  child: Padding(
+                    padding: EdgeInsets.symmetric(vertical: 14),
+                    child: Column(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      children: [
+                        Row(
+                          children: [
+                            Text(
+                              '早期',
+                              style: TextStyle(fontSize: 13, height: 18.5 / 13, color: Color(0xFF666666)),
+                            ),
+                            SizedBox(width: 20),
+                            Expanded(
+                              child: Container(
+                                height: 22,
+                                child: DegreeIndexListView(),
+                              ),
+                            ),
+                          ],
+                        ),
+                        Row(
+                          children: [
+                            Text(
+                              '中期',
+                              style: TextStyle(fontSize: 13, height: 18.5 / 13, color: Color(0xFF666666)),
+                            ),
+                            SizedBox(width: 20),
+                            Expanded(
+                              child: Container(
+                                height: 22,
+                                child: DegreeIndexListView(),
+                              ),
+                            ),
+                          ],
+                        ),
+                        Row(
+                          children: [
+                            Text(
+                              '后期',
+                              style: TextStyle(fontSize: 13, height: 18.5 / 13, color: Color(0xFF666666)),
+                            ),
+                            SizedBox(width: 20),
+                            Expanded(
+                              child: Container(
+                                height: 22,
+                                child: DegreeIndexListView(),
+                              ),
+                            ),
+                          ],
+                        ),
+                      ],
+                    ),
+                  ),
+                )
+              ],
+            ),
+          );
+        },
+        separatorBuilder: (context, index) {
+          return SizedBox(height: 13);
+        });
+  }
+
+  ListView DegreeIndexListView() {
+    return ListView.separated(
+        padding: EdgeInsets.only(right: 20),
+        scrollDirection: Axis.horizontal,
+        itemBuilder: (_, index) {
+          return Image.asset("assets/thinking_core/level.png", width: 20, height: 22);
+        },
+        separatorBuilder: (_, __) {
+          return SizedBox(width: 12.5);
+        },
+        itemCount: 6);
+  }
+
+  Container AppNavBar(BuildContext context) {
+    return Container(
+      width: MediaQuery.of(context).size.width,
+      height: MediaQuery.of(context).padding.top + 44,
+      alignment: Alignment.bottomLeft,
+      child: Row(
+        children: [
+          Container(
+              color: Colors.transparent,
+              padding: EdgeInsets.symmetric(horizontal: 18, vertical: 15),
+              child: Image.asset(
+                "assets/thinking_core/back.png",
+                width: 10.5,
+                height: 19,
+              )),
+          Expanded(
+              child: Text(
+            "能力评估阶段",
+            textAlign: TextAlign.center,
+            style: TextStyle(color: Colors.black, fontSize: 18, height: 25 / 18, fontWeight: FontWeight.w600),
+          )),
+          Padding(
+            padding: EdgeInsets.symmetric(horizontal: 18, vertical: 15),
+            child: SizedBox(width: 10.5),
+          )
+        ],
+      ),
+    );
+  }
+}

+ 189 - 0
lib/src/page/comprehensive_evaluation_report/comprehensive_evaluation_report_page.dart

@@ -0,0 +1,189 @@
+import 'package:flutter/material.dart';
+import 'dart:math' as math;
+import 'package:luojigou_thinking_core/src/view/student_info_list_view.dart';
+import 'package:luojigou_thinking_core/src/data/data_management.dart';
+
+// 综合评估报告&单次评估报告
+class ComprehensiveEvaluationReportPage extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      body: MediaQuery.removePadding(
+        context: context,
+        removeTop: true,
+        child: Container(
+          decoration: BoxDecoration(
+              gradient: LinearGradient(
+            colors: [Color(0xFFBFD6FF), Color(0xFFFEFEFE)],
+            begin: Alignment.topLeft,
+            end: Alignment.bottomRight,
+            stops: [0, 0.5],
+          )),
+          child: Column(
+            children: [
+              AppNavBar(context),
+              SizedBox(height: 17),
+              HeaderView(context),
+              Expanded(
+                child: ContentList(),
+              ),
+              SizedBox(height: 58)
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+
+  Container ContentList() {
+    return Container(
+      margin: EdgeInsets.symmetric(horizontal: 18),
+      padding: EdgeInsets.symmetric(horizontal: 15),
+      decoration: BoxDecoration(color: Color(0xFFFFFFFF), borderRadius: BorderRadius.circular(15), boxShadow: [BoxShadow(color: Color(0xB3BFD8FF), offset: Offset(0, 2), blurRadius: 20, spreadRadius: 0)]),
+      child: Column(
+        children: [
+          SizedBox(height: 18),
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Row(
+                children: [
+                  Image.asset("assets/thinking_core/class_icon.png", width: 18, height: 18),
+                  SizedBox(width: 9.5),
+                  Text("逻辑狗中1班", style: TextStyle(fontSize: 18, height: 22 / 18, fontWeight: FontWeight.w600)),
+                ],
+              ),
+              Text("已评估(13人)", style: TextStyle(color: Color(0xFF666666), fontSize: 16, height: 22.5 / 18, fontWeight: FontWeight.w400))
+            ],
+          ),
+          SizedBox(height: 10),
+          SendToParentsWidget(),
+          Expanded(child: StudentInfoListView(accessoryViewType: AssessAccessoryViewType.Send)),
+        ],
+      ),
+    );
+  }
+
+  Container HeaderView(BuildContext context) {
+    return Container(
+      margin: EdgeInsets.symmetric(horizontal: 18),
+      width: MediaQuery.of(context).size.width,
+      height: (MediaQuery.of(context).size.width - 36) * 179 / 339,
+      child: Stack(
+        fit: StackFit.expand,
+        children: [
+          Image.asset(
+            "assets/thinking_core/comprehensive_evaluat_on_record.png",
+          ),
+          Column(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  SizedBox(height: 22 * (MediaQuery.of(context).size.width - 36) * 179 / 339 / 179),
+                  Padding(padding: EdgeInsets.only(left: 19), child: Text("思维芯游戏", style: TextStyle(color: Colors.white, fontSize: 21, height: 29.5 / 21, fontWeight: FontWeight.w600))),
+                  SizedBox(height: 7 * (MediaQuery.of(context).size.width - 36) * 179 / 339 / 179),
+                  Padding(padding: EdgeInsets.only(left: 19), child: Text("学期综合发展评估", style: TextStyle(color: Colors.white, fontSize: 21, height: 29.5 / 21, fontWeight: FontWeight.w600))),
+                ],
+              ),
+              Padding(padding: EdgeInsets.only(left: 19, bottom: 49 * (MediaQuery.of(context).size.width - 36) * 179 / 339 / 179), child: Text("生成时间:2021.2.3", style: TextStyle(color: Colors.white, fontSize: 11, height: 15 / 11, fontWeight: FontWeight.w500))),
+            ],
+          )
+        ],
+      ),
+    );
+  }
+
+  Container AppNavBar(BuildContext context) {
+    return Container(
+      width: MediaQuery.of(context).size.width,
+      height: MediaQuery.of(context).padding.top + 44,
+      alignment: Alignment.bottomLeft,
+      child: Row(
+        children: [
+          Container(
+              color: Colors.transparent,
+              padding: EdgeInsets.symmetric(horizontal: 18, vertical: 15),
+              child: Image.asset(
+                "assets/thinking_core/back.png",
+                width: 10.5,
+                height: 19,
+              )),
+          Expanded(
+              child: Text(
+            "综合评估记录",
+            textAlign: TextAlign.center,
+            style: TextStyle(color: Colors.black, fontSize: 18, height: 25 / 18, fontWeight: FontWeight.w600),
+          )),
+          Padding(
+            padding: EdgeInsets.symmetric(horizontal: 18, vertical: 15),
+            child: SizedBox(width: 10.5),
+          )
+        ],
+      ),
+    );
+  }
+}
+
+// 发送给家长
+class SendToParentsWidget extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      height: 42,
+      padding: EdgeInsets.only(left: 10, right: 15),
+      decoration: BoxDecoration(
+        gradient: LinearGradient(colors: [Color(0xFFEBF1FF), Color(0xFFDCE6FF)]),
+        borderRadius: BorderRadius.circular(6),
+      ),
+      child: CustomPaint(
+        size: Size(36, 42),
+        painter: SendToParentsPainter(),
+        child: Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            Text("有12份家园共育策略未发送给家长", style: TextStyle(color: Color(0xFF666666), fontSize: 12, height: 16.5 / 12, fontWeight: FontWeight.w400)),
+            GestureDetector(
+              child: Container(
+                width: 84,
+                height: 25,
+                alignment: Alignment.center,
+                decoration: BoxDecoration(
+                  color: Color(0xFF5F87F0),
+                  borderRadius: BorderRadius.circular(12.5),
+                ),
+                child: Text("发给家长", style: TextStyle(color: Color(0xFFFFFFFF), fontSize: 12, height: 16.5 / 12, fontWeight: FontWeight.w400)),
+              ),
+            )
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class SendToParentsPainter extends CustomPainter {
+  @override
+  void paint(Canvas canvas, Size size) {
+    final paint = Paint()
+      ..color = Colors.transparent
+      ..style = PaintingStyle.fill;
+    canvas.drawRRect(RRect.fromLTRBR(0, 0, size.width, size.height, Radius.circular(5)), paint);
+    final path = Path();
+    path.addRRect(RRect.fromRectAndRadius(Rect.fromLTWH(0, 0, 12, 12), Radius.circular(3)));
+    canvas.save();
+    canvas.translate(42, -8);
+    canvas.rotate(math.pi / 4);
+    canvas.drawPath(path, paint..color = Color(0xFFEBF1FF));
+    canvas.restore();
+  }
+
+  @override
+  bool shouldRepaint(covariant CustomPainter oldDelegate) {
+    // TODO: implement shouldRepaint
+    return true;
+  }
+}

+ 193 - 0
lib/src/page/estimate/prepare_to_submit_records.dart

@@ -0,0 +1,193 @@
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/src/view/degree_of_exploration_widget.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar_factory.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/EvaluationRecordCard/evaluation_record_card_side_selection_bar_factory.dart';
+import 'package:luojigou_thinking_core/src/view/student_select_grade/student_select_grade.dart';
+import 'package:luojigou_thinking_core/src/model/comprehensive_capabilities_model.dart';
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+
+//评估记录卡-提价记录
+class PrepareToSubmitRecords extends StatefulWidget {
+  @override
+  PrepareToSubmitRecordsState createState() => new PrepareToSubmitRecordsState();
+}
+
+class PrepareToSubmitRecordsState extends State<PrepareToSubmitRecords> {
+  List<AbilitySelectionTargetModel> dataList = [
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "思维能力与逻辑思考能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "科学能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "探索能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "观察能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "冲突能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "沟通能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "理解能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "学习能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "视听能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "坚持能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "专注能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+    ComprehensiveCapabilitiesModel.fromJson({
+      "domainAbilityName": "练习能力",
+      "isSelected": false,
+      "relationIds": ["1501827369935491076"]
+    }),
+  ];
+
+  late ValueNotifier<int> _notifier;
+
+  late ISideSelectionBarFactory _iSideSelectionBarFactory;
+  late ISideSelectionBar _iSideSelectionBar;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _notifier = ValueNotifier(1);
+    _notifier.addListener(() {
+      print("切换卡片Index");
+      print(_notifier.value);
+    });
+
+    _iSideSelectionBarFactory = EvaluationRecordCardSideSelectionBarFactory();
+    // _iSideSelectionBarFactory = AbilityAssessmentPhaseSideSelectionBarFactory();
+    _iSideSelectionBar = _iSideSelectionBarFactory.getSideSelectionBar(dataList, (selectIndex) {
+      print(selectIndex);
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      body: Container(
+        color: Color(0xFFB4D2FF),
+        width: double.infinity,
+        padding: EdgeInsets.only(left: 15, right: 15, top: 54, bottom: 31),
+        child: Container(
+          decoration: BoxDecoration(
+            color: Color(0xFFFFFFFF),
+            borderRadius: BorderRadius.circular(30),
+          ),
+          child: Column(
+            // mainAxisSize: MainAxisSize.min,
+            children: [
+              SizedBox(height: 30),
+              Row(
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  SizedBox(width: 22),
+                  Container(
+                    width: 34,
+                    height: 34,
+                    decoration: BoxDecoration(
+                      color: Color(0xFFEAF9FF),
+                      borderRadius: BorderRadius.circular(17),
+                    ),
+                  ),
+                  SizedBox(width: 9),
+                  Text(
+                    "评估记录卡",
+                    style: TextStyle(fontSize: 20, height: 1.1, fontWeight: FontWeight.w500),
+                  )
+                ],
+              ),
+              SizedBox(height: 23),
+              Expanded(
+                child: Row(children: [
+                  SizedBox(width: 19),
+                  _iSideSelectionBar.getSideSelectionBar(),
+                  SizedBox(width: 28),
+                  Expanded(
+                    child: GridView.builder(
+                        // physics: NeverScrollableScrollPhysics(),
+                        padding: EdgeInsets.only(right: 21),
+                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+                          crossAxisCount: 4,
+                          mainAxisSpacing: 22,
+                          //96 + 36*4
+                          crossAxisSpacing: (MediaQuery.of(context).size.width - 291) / 3,
+                          childAspectRatio: 36 / 71,
+                        ),
+                        itemCount: 40,
+                        itemBuilder: (_, index) {
+                          return StudentSlectGrade(grade: '早期', isSelect: true);
+                        }),
+                  ),
+                ]),
+              ),
+              SizedBox(height: 38),
+              GestureDetector(
+                onTap: () {},
+                child: Container(
+                  width: 133,
+                  height: 42,
+                  alignment: Alignment.center,
+                  decoration: BoxDecoration(
+                    borderRadius: BorderRadius.circular(21),
+                    border: Border.all(
+                      color: Color(0xFF6AA5FF),
+                      width: 1,
+                    ),
+                  ),
+                  child: Text(
+                    "提交记录",
+                    style: TextStyle(
+                      fontSize: 16,
+                      height: 18 / 16,
+                      color: Color(0xFF5F87F0),
+                      fontWeight: FontWeight.w500,
+                    ),
+                  ),
+                ),
+              ),
+              SizedBox(height: 29),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}

+ 382 - 0
lib/src/page/evaluation_records_or_reports/evaluation_records_or_reports_page.dart

@@ -0,0 +1,382 @@
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/src/view/evaluation_records/evaluation_records_page_view.dart';
+
+//评估记录/报告
+class EvaluationRecordsOrReportsPpage extends StatefulWidget {
+  @override
+  EvaluationRecordsOrReportsPpageState createState() => new EvaluationRecordsOrReportsPpageState();
+}
+
+class EvaluationRecordsOrReportsPpageState extends State<EvaluationRecordsOrReportsPpage> {
+  late ValueNotifier<int> _notifier;
+  late PageController _pageController;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _pageController = PageController(initialPage: 0);
+    _notifier = ValueNotifier(0);
+    _notifier.addListener(() {
+      _pageController.jumpToPage(_notifier.value);
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      body: Container(
+        decoration: BoxDecoration(gradient: LinearGradient(colors: [Color(0xFFBFD6FF), Color(0xFFFEFEFE)], begin: Alignment.topLeft, end: Alignment.bottomRight, stops: [0, 0.5])),
+        child: Column(
+          children: [
+            AppNavBar(context),
+            EvaluationRecordsTabBar(notifier: _notifier, categorys: [TbaBarModel(), TbaBarModel(), TbaBarModel()]),
+            EvaluationPageView(context),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Container AppNavBar(BuildContext context) {
+    return Container(
+      width: MediaQuery
+          .of(context)
+          .size
+          .width,
+      height: MediaQuery
+          .of(context)
+          .padding
+          .top + 44,
+      alignment: Alignment.bottomLeft,
+      child: Stack(
+        alignment: Alignment.bottomCenter,
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Container(
+                  color: Colors.transparent,
+                  padding: EdgeInsets.symmetric(horizontal: 18, vertical: 15),
+                  child: Image.asset(
+                    "assets/thinking_core/back.png",
+                    width: 10.5,
+                    height: 19,
+                  )),
+              Padding(
+                padding: EdgeInsets.only(right: 18),
+                child: Text(
+                  "逻辑狗小班",
+                  textAlign: TextAlign.center,
+                  style: TextStyle(color: Color(0xFF666666), fontSize: 14, height: 20 / 14, fontWeight: FontWeight.w400),
+                ),
+              )
+            ],
+          ),
+          Padding(
+            padding: EdgeInsets.only(bottom: 12),
+            child: Text(
+              "评估记录/报告",
+              textAlign: TextAlign.center,
+              style: TextStyle(color: Colors.black, fontSize: 18, height: 25 / 18, fontWeight: FontWeight.w600),
+            ),
+          )
+        ],
+      ),
+    );
+  }
+
+  Widget EvaluationPageView(BuildContext context) {
+    List<Widget> list = List.filled(3, EvaluationRecordsPageView()).toList();
+
+    return Expanded(
+      child: PageView(
+        controller: _pageController,
+        children: list,
+        onPageChanged: (index){
+          _notifier.value = index;
+        },
+      ),
+    );
+  }
+}
+
+class TbaBarModel {}
+
+//评估记录TabBar
+class EvaluationRecordsTabBar extends StatefulWidget {
+  final ValueNotifier<int> notifier;
+  final List<TbaBarModel> categorys;
+
+  const EvaluationRecordsTabBar({
+    Key? key,
+    required this.notifier,
+    required this.categorys,
+  }) : super(key: key);
+
+  @override
+  EvaluationRecordsTabBarState createState() => new EvaluationRecordsTabBarState();
+}
+
+class EvaluationRecordsTabBarState extends State<EvaluationRecordsTabBar> {
+  late int _currentIndex;
+  late ScrollController _scrollController;
+  GlobalKey _key = GlobalKey();
+  late List<GlobalKey> _tabKeys;
+
+  @override
+  void initState() {
+    super.initState();
+    _currentIndex = widget.notifier.value;
+    _scrollController = ScrollController();
+    _tabKeys = widget.categorys.map((TbaBarModel tab) => GlobalKey()).toList();
+    widget.notifier.addListener(_changeIndex);
+  }
+
+  @override
+  void dispose() {
+    widget.notifier.removeListener(_changeIndex);
+    _scrollController.dispose();
+    super.dispose();
+  }
+
+  void _changeIndex() {
+    if (_currentIndex != widget.notifier.value) {
+      setState(() {
+        _currentIndex = widget.notifier.value;
+        _scrollToCurrentIndex();
+      });
+    }
+  }
+
+  void _scrollToCurrentIndex() {
+    double distanceToLeft = 18;
+    for (int i = 0; i < _currentIndex; i++) {
+      distanceToLeft += 16.0 + _tabKeys[i].currentContext!.size!.width;
+    }
+    double distanceToWindow = _scrollController.position.viewportDimension / 2 - _tabKeys[_currentIndex].currentContext!.size!.width / 2;
+    _scrollController.animateTo(
+      distanceToLeft - distanceToWindow,
+      duration: Duration(milliseconds: 200),
+      curve: Curves.easeOut,
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    List<Widget> tabs = List.generate(widget.categorys.length, (index) {
+      return Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 8),
+        child: GestureDetector(
+          onTap: () {
+            if (widget.notifier.value != index) {
+              widget.notifier.value = index;
+            }
+          },
+          child: RecordCellView(index, context),
+        ),
+      );
+    });
+
+    return Container(
+      height: 169.0 + 44,
+      child: SingleChildScrollView(
+        key: _key,
+        controller: _scrollController,
+        physics: ClampingScrollPhysics(),
+        padding: EdgeInsets.symmetric(horizontal: 10),
+        scrollDirection: Axis.horizontal,
+        child: Row(children: tabs),
+      ),
+    );
+  }
+
+  //评估报告
+  Container ReportCellView(int index, BuildContext context) {
+    return Container(
+      decoration: BoxDecoration(
+        color: Color(0xFFFFFFFF),
+        borderRadius: BorderRadius.circular(15),
+        boxShadow: [BoxShadow(color: Color(0xB3BFD8FF), offset: Offset(0, 2), blurRadius: 20, spreadRadius: 0)],
+      ),
+      key: _tabKeys[index],
+      height: double.infinity,
+      width: 289,
+      //记录:MediaQuery.of(context).size.width - 62 报告:MediaQuery.of(context).size.width - 86
+      margin: EdgeInsets.symmetric(vertical: 22),
+      child: Column(
+        children: [
+          Container(
+            width: double.infinity,
+            alignment: Alignment.centerLeft,
+            height: 37,
+            decoration: BoxDecoration(color: Color(0xFFD2DFFF), borderRadius: BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15))),
+            child: Stack(
+              fit: StackFit.expand,
+              alignment: Alignment.center,
+              children: [
+                Image.asset("assets/thinking_core/report_tab_bar_bg.png", fit: BoxFit.fitWidth),
+                Positioned(
+                  left: 15,
+                  child: Text(
+                    "综合区",
+                    textAlign: TextAlign.center,
+                    style: TextStyle(color: Color(0xFF5F87F0), fontSize: 18, height: 23.5 / 18, fontFamily: "YouSheBiaoTiHei"),
+                  ),
+                )
+              ],
+            ),
+          ),
+          Expanded(
+              child: GridView.builder(
+                  physics: NeverScrollableScrollPhysics(),
+                  padding: EdgeInsets.all(20),
+                  itemCount: 5,
+                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+                      crossAxisCount: 3, //横轴三个子widget
+                      mainAxisSpacing: 12,
+                      crossAxisSpacing: 12,
+                      childAspectRatio: 75 / 40),
+                  itemBuilder: (_, index) {
+                    return Container(
+                      // padding: EdgeInsets.symmetric(horizontal: 7.5, vertical: 11),
+                      alignment: Alignment.center,
+                      decoration: BoxDecoration(
+                        color: Color(0xFFDDE7FF),
+                        borderRadius: BorderRadius.circular(7),
+                      ),
+                      child: Text(
+                        "观察能力",
+                        textAlign: TextAlign.center,
+                        maxLines: 2,
+                        style: TextStyle(color: Color(0xFF5F87F0),
+                            fontSize: 13,
+                            height: 18.5 / 13,
+                            fontWeight: FontWeight.w500,
+                            overflow: TextOverflow.ellipsis),
+                      ),
+                    );
+                  }))
+        ],
+      ),
+    );
+  }
+
+  // 评估记录
+  Container RecordCellView(int index, BuildContext context) {
+    return Container(
+      decoration: BoxDecoration(
+        color: Color(0xFFFFFFFF),
+        borderRadius: BorderRadius.circular(15),
+        boxShadow: [BoxShadow(color: Color(0xB3BFD8FF), offset: Offset(0, 2), blurRadius: 20, spreadRadius: 0)],
+      ),
+      key: _tabKeys[index],
+      height: double.infinity,
+      width: MediaQuery
+          .of(context)
+          .size
+          .width - 62,
+      margin: EdgeInsets.symmetric(vertical: 22),
+      child: Column(
+        children: [
+          Container(
+            width: double.infinity,
+            alignment: Alignment.centerLeft,
+            padding: EdgeInsets.only(left: 15),
+            height: 37,
+            decoration: BoxDecoration(color: Color(0xFFD2DFFF), borderRadius: BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15))),
+            child: Text(
+              "科学探索区域",
+              textAlign: TextAlign.center,
+              style: TextStyle(color: Color(0xFF5F87F0), fontSize: 18, height: 23.5 / 18, fontFamily: "YouSheBiaoTiHei"),
+            ),
+          ),
+          SizedBox(height: 15),
+          Expanded(
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Container(
+                  // color: Colors.red,
+                  child: Row(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    children: [
+                      SizedBox(width: 15),
+                      ClipOval(
+                        child: Container(width: 4, height: 4, color: Color(0xFF5F87F0)),
+                      ),
+                      SizedBox(width: 4),
+                      Text(
+                        "活动名称:《有趣的溶解》",
+                        style: TextStyle(color: Color(0xFF333333), fontSize: 14, fontWeight: FontWeight.w500),
+                      ),
+                    ],
+                  ),
+                ),
+                Container(
+                  // color: Colors.orange,
+                  child: Row(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    children: [
+                      SizedBox(width: 15),
+                      ClipOval(
+                        child: Container(width: 4, height: 4, color: Color(0xFF5F87F0)),
+                      ),
+                      SizedBox(width: 4),
+                      Text(
+                        "核心领域:科学领域",
+                        style: TextStyle(color: Color(0xFF333333), fontSize: 14, fontWeight: FontWeight.w500),
+                      ),
+                    ],
+                  ),
+                ),
+                Container(
+                  // color: Colors.cyan,
+                  child: Row(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    children: [
+                      SizedBox(width: 15),
+                      ClipOval(
+                        child: Container(width: 4, height: 4, color: Color(0xFF5F87F0)),
+                      ),
+                      SizedBox(width: 4),
+                      Text(
+                        "核心观察能力:探索与研究",
+                        style: TextStyle(color: Color(0xFF333333), fontSize: 14, fontWeight: FontWeight.w500),
+                      ),
+                    ],
+                  ),
+                ),
+              ],
+            ),
+          ),
+          Container(
+            margin: EdgeInsets.symmetric(vertical: 16, horizontal: 15),
+            height: 19,
+            // color: Colors.red,
+            child: ListView.separated(
+                itemCount: 4,
+                scrollDirection: Axis.horizontal,
+                separatorBuilder: (context, index) {
+                  return SizedBox(width: 8);
+                },
+                itemBuilder: (context, index) {
+                  return Container(
+                    height: 19,
+                    padding: EdgeInsets.only(left: 2.5, right: 1.5),
+                    decoration: BoxDecoration(
+                      border: Border.all(color: Color(0xFFCBCBCB), width: 1),
+                      borderRadius: BorderRadius.circular(4),
+                    ),
+                    child: Text(
+                      "反应能力",
+                      style: TextStyle(color: Color(0xFF999999), fontSize: 12, height: 16.5 / 12, fontWeight: FontWeight.w500),
+                    ),
+                  );
+                }),
+          )
+        ],
+      ),
+    );
+  }
+}

+ 155 - 0
lib/src/page/playroom/game_park_page.dart

@@ -0,0 +1,155 @@
+import 'package:flutter/material.dart';
+
+class GameParkPage extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Stack(
+      children: [
+        SingleChildScrollView(
+          child: Column(
+            children: [FourMajorAreasView(), ComprehensiveCapabilityAssessmentView()],
+          ),
+        ),
+        Positioned(
+          bottom: 213 - 34.0,
+          right: 18,
+          child: Container(
+            width: 66,
+            height: 66,
+            decoration:
+                BoxDecoration(color: Color(0xFFFF9292), borderRadius: BorderRadius.circular(33), border: Border.all(color: Colors.white, width: 3), boxShadow: [BoxShadow(color: Color(0x33526ABF), offset: Offset(0, 11), blurRadius: 12, spreadRadius: 0)]),
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                Icon(
+                  Icons.add,
+                  color: Colors.white,
+                ),
+                Text(
+                  "记录",
+                  style: TextStyle(color: Color(0xFFFFFFFF), fontWeight: FontWeight.w600, fontSize: 14, height: 20 / 14),
+                )
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class FourMajorAreasView extends StatelessWidget {
+  List<Color> colorList = [Color(0XFF64B794), Color(0xFF69A9F9), Color(0xFFFB8972), Color(0xFFE5C356)];
+  List<String> titleList = ["《模式大闯关大闯关》", "《有趣的溶解》", "《我喜欢的艺术游戏》", "《魔法读书会》"];
+
+  @override
+  Widget build(BuildContext context) {
+    List<Widget> subviews = [];
+    for (int i = 0; i < colorList.length; i++) {
+      subviews.add(Container(
+        height: (MediaQuery.of(context).size.width - 36) / 2 * 150 / 174,
+        width: (MediaQuery.of(context).size.width - 36) / 2,
+        child: Stack(
+          alignment: Alignment.center,
+          children: [
+            ClipRRect(
+              child: Image.asset("assets/thinking_core/gaming_activities_bg${i + 1}.png"),
+              borderRadius: BorderRadius.circular(13),
+            ),
+            i % 2 == 0
+                ? Positioned(
+                    left: 5,
+                    bottom: 23,
+                    child: Text(
+                      titleList[i],
+                      style: TextStyle(fontSize: 17, height: 24 / 17, color: colorList[i], fontWeight: FontWeight.w600),
+                    ),
+                  )
+                : Positioned(
+                    right: 5,
+                    top: 46,
+                    child: Text(
+                      titleList[i],
+                      style: TextStyle(fontSize: 17, height: 24 / 17, color: colorList[i], fontWeight: FontWeight.w600),
+                    ),
+                  ),
+            Positioned(
+                right: 5,
+                bottom: 3,
+                child: Container(
+                  width: 24,
+                  height: 24,
+                  // padding: EdgeInsets.symmetric(horizontal: 6),
+                  decoration: BoxDecoration(
+                    color: Color(0xA1FFFFFF),
+                    borderRadius: BorderRadius.circular(12),
+                  ),
+                  child: Icon(
+                    Icons.arrow_forward_outlined,
+                    color: colorList[i],
+                  ),
+                ))
+          ],
+        ),
+      ));
+    }
+
+    return Container(
+      width: double.infinity,
+      padding: EdgeInsets.symmetric(horizontal: 18),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          SizedBox(height: 21),
+          Text("四大领域游戏活动", style: TextStyle(fontSize: 25, height: 32.5 / 25, fontFamily: "YouSheBiaoTiHei")),
+          SizedBox(height: 20),
+          Wrap(runSpacing: 21, spacing: 0, children: subviews),
+          SizedBox(height: 50),
+        ],
+      ),
+    );
+  }
+}
+
+class ComprehensiveCapabilityAssessmentView extends StatelessWidget {
+  List<Color> colorList = [Color(0XFFA43A3A), Color(0xFF3A57A4), Color(0xFF3A99A4), Color(0xFF753AA4)];
+  List<String> titleList = ["观察能力", "冲突解决", "沟通与对话能力", "坚持与专注能力"];
+
+  @override
+  Widget build(BuildContext context) {
+    List<Widget> subviews = [];
+    for (int i = 0; i < colorList.length; i++) {
+      subviews.add(Container(
+        height: (MediaQuery.of(context).size.width - 57) / 2 * 70 / 159,
+        width: (MediaQuery.of(context).size.width - 57) / 2,
+        child: Stack(
+          alignment: Alignment.center,
+          children: [
+            ClipRRect(
+              child: Image.asset("assets/thinking_core/comprehensive_capabilities_bg${i + 1}.png"),
+              borderRadius: BorderRadius.circular(13),
+            ),
+            Text(
+              titleList[i],
+              style: TextStyle(fontSize: 17, height: 24 / 17, color: colorList[i], fontWeight: FontWeight.w600),
+            ),
+          ],
+        ),
+      ));
+    }
+
+    return Container(
+      width: double.infinity,
+      padding: EdgeInsets.symmetric(horizontal: 18),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Text("综合能力评估", style: TextStyle(fontSize: 25, height: 32.5 / 25, fontFamily: "YouSheBiaoTiHei")),
+          SizedBox(height: 20),
+          Wrap(runSpacing: 21, spacing: 21, children: subviews),
+          SizedBox(height: 65.5),
+        ],
+      ),
+    );
+  }
+}

+ 160 - 0
lib/src/page/playroom/history_page.dart

@@ -0,0 +1,160 @@
+import 'dart:ui';
+
+import 'package:flutter/material.dart';
+
+class HistoryPage extends StatefulWidget {
+  @override
+  HistoryPageState createState() => new HistoryPageState();
+}
+
+class HistoryPageState extends State<HistoryPage> {
+  @override
+  Widget build(BuildContext context) {
+    return MediaQuery.removePadding(
+      removeTop: true,
+      context: context,
+      child: ListView.separated(
+          padding: EdgeInsets.only(top: 22, bottom: 15),
+          itemBuilder: (context, index) {
+            if (index == 0) {
+              return Container(
+                margin: EdgeInsets.symmetric(horizontal: 18),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Stack(
+                      // alignment: Alignment.centerLeft,
+                      children: [
+                        Image.asset("assets/thinking_core/comprehensive_evaluat_on_record.png"),
+                        Center(
+                          child: ClipRRect(
+                            child: BackdropFilter(
+                              filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
+                              child: Opacity(
+                                opacity: 0.3,
+                                child: Container(
+                                  width: MediaQuery.of(context).size.width - 36,
+                                  height: (MediaQuery.of(context).size.width - 36) * 171 / 339,
+                                  decoration: BoxDecoration(color: Colors.white),
+                                ),
+                              ),
+                            ),
+                            borderRadius: BorderRadius.circular(15),
+                          ),
+                        ),
+                        Positioned(
+                          left: 18,
+                          top: (MediaQuery.of(context).size.width - 36) * 32 / 339,
+                          child: Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              Text(
+                                "思维芯游戏",
+                                style: TextStyle(fontSize: 21, height: 29.5 / 21, fontWeight: FontWeight.w600, color: Colors.white),
+                              ),
+                              SizedBox(height: 7),
+                              Text(
+                                "学期综合发展评估",
+                                style: TextStyle(fontSize: 21, height: 29.5 / 21, fontWeight: FontWeight.w600, color: Colors.white),
+                              ),
+                            ],
+                          ),
+                        ),
+                        Positioned(top: 0, right: 0, child: Image.asset("assets/thinking_core/lock.png", width: 45, height: 45)),
+                        Positioned(
+                          right: 27,
+                          top: (MediaQuery.of(context).size.width - 36) * 48.5 / 339,
+                          child: Container(
+                            width: 107,
+                            height: 38,
+                            alignment: Alignment.center,
+                            decoration: BoxDecoration(color: Color(0xFF5F87F0), borderRadius: BorderRadius.circular(19)),
+                            child: Text(
+                              "立即生成",
+                              style: TextStyle(color: Colors.white, fontSize: 16, height: 22.5 / 16, fontWeight: FontWeight.w500),
+                            ),
+                          ),
+                        )
+                      ],
+                    ),
+                    Text(
+                      "评估历史记录",
+                      style: TextStyle(fontSize: 18, height: 25 / 18, fontWeight: FontWeight.w600),
+                    ),
+                  ],
+                ),
+              );
+            }
+            return HistoryCellView();
+          },
+          separatorBuilder: (context, index) {
+            return SizedBox(height: index == 0 ? 17 : 15);
+          },
+          itemCount: 6),
+    );
+  }
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+  }
+
+  Container HistoryCellView() {
+    return Container(
+      height: 120,
+      width: double.infinity,
+      margin: EdgeInsets.symmetric(horizontal: 18),
+      decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [BoxShadow(color: Color(0x8FD5D9E3), offset: Offset(1, 5), spreadRadius: 0, blurRadius: 25)]),
+      child: Row(
+        crossAxisAlignment: CrossAxisAlignment.end,
+        children: [
+          SizedBox(width: 15),
+          Expanded(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SizedBox(height: 20),
+                Text(
+                  "思维芯游戏发展评估记录",
+                  style: TextStyle(fontSize: 16, height: 22.5 / 16, fontWeight: FontWeight.w500),
+                ),
+                SizedBox(height: 17.5),
+                Row(
+                  children: [
+                    Image.asset("assets/thinking_core/time.png", width: 14, height: 14),
+                    SizedBox(width: 5),
+                    Text(
+                      "思维芯游戏发展评估记录",
+                      style: TextStyle(fontSize: 14, height: 20 / 14, fontWeight: FontWeight.w400, color: Color(0xFF666666)),
+                    ),
+                  ],
+                ),
+                SizedBox(height: 11),
+                Row(
+                  children: [
+                    Image.asset("assets/thinking_core/people.png", width: 14, height: 14),
+                    SizedBox(width: 5),
+                    Text(
+                      "记录人:张老师",
+                      style: TextStyle(fontSize: 14, height: 20 / 14, fontWeight: FontWeight.w400, color: Color(0xFF666666)),
+                    ),
+                  ],
+                )
+              ],
+            ),
+          ),
+          ClipRRect(
+            borderRadius: BorderRadius.circular(15),
+            child: Image.asset(
+              "assets/thinking_core/record_bg.png",
+              width: 113,
+              height: 107,
+              fit: BoxFit.cover,
+            ),
+          )
+        ],
+      ),
+    );
+  }
+}

+ 201 - 0
lib/src/page/playroom/playroom_page.dart

@@ -0,0 +1,201 @@
+import 'dart:ui';
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/src/data/data_management.dart';
+import 'game_park_page.dart';
+import 'history_page.dart';
+
+/// 思维芯游戏室列表
+class PlayroomPage extends StatefulWidget {
+  @override
+  PlayroomPageState createState() => new PlayroomPageState();
+}
+
+class PlayroomPageState extends State<PlayroomPage> {
+  late PageController _pageController;
+  late ValueNotifier<int> _valueNotifier;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _pageController = PageController(initialPage: 0);
+    _valueNotifier = ValueNotifier(0);
+    _valueNotifier.addListener(() {
+      _pageController.jumpToPage(_valueNotifier.value);
+    });
+  }
+
+  @override
+  void dispose() {
+    // TODO: implement dispose
+    super.dispose();
+    _pageController.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      body: Container(
+        decoration: BoxDecoration(gradient: LinearGradient(colors: [Color(0xFFADCCFF), Color(0xFF6EA7FF)], begin: Alignment.topRight, end: Alignment.topLeft)),
+        child: Column(
+          children: [
+            NavigationBar(
+              valueNotifier: _valueNotifier,
+            ),
+            Expanded(
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: Color(0xFFFDFDFD),
+                    borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)),
+                  ),
+                  child: PageView(
+                    controller: _pageController,
+                    onPageChanged: (index) {
+                      _valueNotifier.value = index;
+                    },
+                    children: [
+                      GameParkPage(),
+                      HistoryPage(),
+                    ],
+                  ),
+                ))
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class NavigationBar extends StatefulWidget {
+  final ValueNotifier<int> valueNotifier;
+
+  const NavigationBar({Key? key, required this.valueNotifier}) : super(key: key);
+
+  @override
+  NavigationBarState createState() => new NavigationBarState();
+}
+
+class NavigationBarState extends State<NavigationBar> {
+  ToggleState _toggleState = ToggleState.GamePark;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    widget.valueNotifier.addListener(() {
+      setState(() {
+        _toggleState = [ToggleState.GamePark, ToggleState.History][widget.valueNotifier.value];
+      });
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      height: MediaQuery.of(context).padding.top + 44,
+      padding: EdgeInsets.only(left: 18, right: 18, bottom: 8.5),
+      alignment: Alignment.bottomCenter,
+      child: Row(
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: [
+          Row(
+            crossAxisAlignment: CrossAxisAlignment.end,
+            children: [
+              GestureDetector(
+                onTap: () {},
+                child: Container(
+                  width: 25,
+                  height: 25,
+                  alignment: Alignment.center,
+                  decoration: BoxDecoration(
+                    color: Color(0x4DFFFFFF),
+                    borderRadius: BorderRadius.circular(12.5),
+                  ),
+                  child: Image.asset(
+                    "assets/thinking_core/back_white.png",
+                    width: 8.5,
+                    height: 13,
+                  ),
+                ),
+              ),
+              SizedBox(width: 15),
+              getSelectButton(ToggleState.GamePark, _toggleState == ToggleState.GamePark, 0),
+              SizedBox(width: 20),
+              getSelectButton(ToggleState.History, _toggleState == ToggleState.History, 1),
+            ],
+          ),
+          Container(
+            width: 88,
+            height: 30,
+            decoration: BoxDecoration(color: Color(0xFFFFFFFF), borderRadius: BorderRadius.circular(15)),
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                Image.asset("assets/thinking_core/calendar.png", width: 13, height: 11),
+                SizedBox(width: 7),
+                Text(
+                  "3月",
+                  style: TextStyle(fontSize: 12, height: 16.5 / 12, color: Color(0xFF3A4CA8), fontWeight: FontWeight.w500),
+                ),
+                SizedBox(width: 2),
+                Container(
+                  width: 7,
+                  height: 7,
+                  child: CustomPaint(
+                    painter: TrianglePainter(),
+                  ),
+                )
+              ],
+            ),
+          )
+        ],
+      ),
+    );
+  }
+
+  Widget getSelectButton(ToggleState toggleState, bool isSelected, int tag) {
+    String _title = toggleState == ToggleState.GamePark ? "游戏乐园" : "历史记录";
+    TextStyle _style = isSelected ? TextStyle(color: Color(0xFFFFFFFF), fontSize: 18, height: 25 / 18, fontWeight: FontWeight.w600) : TextStyle(color: Color(0xB3FFFFFF), fontSize: 15, height: 21 / 15, fontWeight: FontWeight.w500);
+
+    return GestureDetector(
+      onTap: () {
+        setState(() {
+          _toggleState = toggleState;
+          widget.valueNotifier.value = tag;
+        });
+      },
+      child: Container(
+        // padding: EdgeInsets.symmetric(vertical: 20, horizontal: 13),
+        color: Colors.transparent,
+        child: Text(
+          _title,
+          style: _style,
+        ),
+      ),
+    );
+  }
+}
+
+class TrianglePainter extends CustomPainter {
+  @override
+  void paint(Canvas canvas, Size size) {
+    // TODO: implement paint
+    Paint paint = Paint()
+      ..color = Color(0xFF3A4CA8)
+      ..strokeWidth = 2;
+    Path path = Path();
+
+    path.moveTo(0, size.height / 2);
+    path.lineTo(size.width / 2, size.height);
+    path.lineTo(size.width, size.height / 2);
+    path.close();
+
+    canvas.drawPath(path, paint);
+  }
+
+  @override
+  bool shouldRepaint(covariant CustomPainter oldDelegate) {
+    // TODO: implement shouldRepaint
+    return true;
+  }
+}

+ 86 - 0
lib/src/view/SideSelectionBar/AbilityAssessmentPhase/a_a_p_side_selection_bar.dart

@@ -0,0 +1,86 @@
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+
+/* 能力评估阶段侧边选择栏 */
+class AAPSideSelectionBar extends StatefulWidget {
+  final List<AbilitySelectionTargetModel> dataList;
+  final Function(int selectIndex) selectAction;
+
+  const AAPSideSelectionBar({Key? key, required this.dataList, required this.selectAction}) : super(key: key);
+
+  @override
+  AAPSideSelectionBarState createState() => new AAPSideSelectionBarState();
+}
+
+class AAPSideSelectionBarState extends State<AAPSideSelectionBar> {
+  late int _oldSelectIndex;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _oldSelectIndex = 0;
+    widget.dataList.first.setIsSelected = true;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: 85,
+      margin: EdgeInsets.only(top: 20.0, bottom:  64.5),
+      // padding: EdgeInsets.symmetric(vertical: 17),
+      child: ListView.separated(
+        padding: EdgeInsets.symmetric(vertical: 17),
+      itemCount: widget.dataList.length,
+        itemBuilder: (context, index) {
+          return BarItems(widget.dataList[index], index);
+        },
+        separatorBuilder: (_, __) {
+          return SizedBox(height: 5);
+        },
+      ),
+    );
+  }
+
+  Widget BarItems(AbilitySelectionTargetModel model, int index) {
+    return GestureDetector(
+      onTap: () {
+        BarItemSelectAction(index);
+      },
+      child: Container(
+        width: 85,
+        height: 58,
+        alignment: Alignment.center,
+        padding: EdgeInsets.only(left: 2.5, right: 5.5),
+        margin: EdgeInsets.only(right: model.getIsSelected ? 18 : 21),
+        decoration: BoxDecoration(
+          color: model.getIsSelected ? Color(0xFF5F87F0) : Color(0xFFFFFFFF),
+          borderRadius: BorderRadius.only(topRight: Radius.circular(10), bottomRight: Radius.circular(10)),
+        ),
+        child: Text(
+          model.getDomainAbilityName,
+          maxLines: 2,
+          textAlign: TextAlign.center,
+          style: TextStyle(
+            color: model.getIsSelected ? Color(0xFFFFFFFF) : Color(0xFFA4BBF9),
+            fontSize: 14,
+            fontWeight:  model.getIsSelected ? FontWeight.w600 : FontWeight.w500,
+            height: 20 / 14,
+            overflow: TextOverflow.ellipsis,
+          ),
+        ),
+      ),
+    );
+  }
+
+  void BarItemSelectAction(int index) {
+    if (_oldSelectIndex != index) {
+      setState(() {
+        widget.dataList[_oldSelectIndex].setIsSelected = false;
+        widget.dataList[index].setIsSelected = true;
+        _oldSelectIndex = index;
+        widget.selectAction(index);
+      });
+    }
+  }
+}

+ 22 - 0
lib/src/view/SideSelectionBar/AbilityAssessmentPhase/ability_assessment_phase_side_selection_bar.dart

@@ -0,0 +1,22 @@
+import '../i_side_selection_bar.dart';
+import 'a_a_p_side_selection_bar.dart';
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+
+/* 评估记录卡侧边选择栏 */
+class AbilityAssessmentPhaseSideSelectionBar with ISideSelectionBar{
+  late AAPSideSelectionBar _aapSideSelectionBar;
+
+  final List<AbilitySelectionTargetModel> dataList;
+  final Function(int selectIndex) selectAction;
+
+  AbilityAssessmentPhaseSideSelectionBar({required this.dataList, required this.selectAction}){
+    _aapSideSelectionBar = AAPSideSelectionBar(dataList: dataList, selectAction: selectAction);
+  }
+
+  @override
+  Widget getSideSelectionBar() {
+    // TODO: implement getSideSelectionBar
+    return _aapSideSelectionBar;
+  }
+}

+ 12 - 0
lib/src/view/SideSelectionBar/AbilityAssessmentPhase/ability_assessment_phase_side_selection_bar_factory.dart

@@ -0,0 +1,12 @@
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar.dart';
+import '../i_side_selection_bar_factory.dart';
+import 'ability_assessment_phase_side_selection_bar.dart';
+
+class AbilityAssessmentPhaseSideSelectionBarFactory with ISideSelectionBarFactory{
+  @override
+  ISideSelectionBar getSideSelectionBar(List<AbilitySelectionTargetModel> dataList, Function(int selectIndex) selectAction) {
+    // TODO: implement getSideSelectionBar
+      return AbilityAssessmentPhaseSideSelectionBar(dataList: dataList, selectAction: selectAction);
+  }
+}

+ 80 - 0
lib/src/view/SideSelectionBar/EvaluationRecordCard/e_r_c_side_selection_bar.dart

@@ -0,0 +1,80 @@
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+import '../../degree_of_exploration_widget.dart';
+
+/* 评估记录卡侧边选择栏 */
+class ERCSideSelectionBar extends StatefulWidget {
+  final List<AbilitySelectionTargetModel> dataList;
+  final Function(int selectIndex) selectAction;
+
+  const ERCSideSelectionBar({Key? key, required this.dataList, required this.selectAction}) : super(key: key);
+
+  @override
+  ERCSideSelectionBarState createState() => new ERCSideSelectionBarState();
+}
+
+class ERCSideSelectionBarState extends State<ERCSideSelectionBar> {
+  late int _oldSelectIndex;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _oldSelectIndex = 0;
+    widget.dataList.first.setIsSelected = true;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: 40,
+      decoration: BoxDecoration(
+        color: Color(0xFFF8F6F6),
+        borderRadius: BorderRadius.circular(10),
+      ),
+      child: MediaQuery.removePadding(
+        context: context,
+        removeTop: true,
+        child: ListView.builder(
+            itemCount: widget.dataList.length,
+            itemBuilder: (context, index) {
+              return BarItems(widget.dataList[index], index);
+            }),
+      ),
+    );
+  }
+
+  Widget BarItems(AbilitySelectionTargetModel model, int index) {
+    return GestureDetector(
+      onTap: () {
+        BarItemSelectAction(index);
+      },
+      child: Container(
+        width: 40,
+        height: 62,
+        alignment: Alignment.center,
+        padding: EdgeInsets.symmetric(horizontal: 8),
+        decoration: BoxDecoration(
+          color: model.getIsSelected ? Color(0xFFF99A94) : Colors.transparent,
+          borderRadius: BorderRadius.circular(10),
+        ),
+        child: Text(
+          model.getDomainAbilityName,
+          maxLines: 3,
+          style: TextStyle(color: model.getIsSelected ? Color(0xFFFFFFFF) : Color(0xFFB6A7A7), fontSize: 12, height: 16 / 12, overflow: TextOverflow.ellipsis),
+        ),
+      ),
+    );
+  }
+
+  void BarItemSelectAction(int index) {
+    if (_oldSelectIndex != index) {
+      setState(() {
+        widget.dataList[_oldSelectIndex].setIsSelected = false;
+        widget.dataList[index].setIsSelected = true;
+        _oldSelectIndex = index;
+        widget.selectAction(index);
+      });
+    }
+  }
+}

+ 22 - 0
lib/src/view/SideSelectionBar/EvaluationRecordCard/evaluation_record_card_side_selection_bar.dart

@@ -0,0 +1,22 @@
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar.dart';
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+import 'e_r_c_side_selection_bar.dart';
+import 'package:flutter/material.dart';
+
+/* 评估记录卡侧边选择栏 */
+class EvaluationRecordCardSideSelectionBar with ISideSelectionBar{
+  late ERCSideSelectionBar _ercSideSelectionBar;
+
+  final List<AbilitySelectionTargetModel> dataList;
+  final Function(int selectIndex) selectAction;
+
+  EvaluationRecordCardSideSelectionBar({required this.dataList, required this.selectAction}){
+    _ercSideSelectionBar = ERCSideSelectionBar(dataList: dataList, selectAction: selectAction);
+  }
+
+  @override
+  Widget getSideSelectionBar() {
+    // TODO: implement getSideSelectionBar
+    return _ercSideSelectionBar;
+  }
+}

+ 12 - 0
lib/src/view/SideSelectionBar/EvaluationRecordCard/evaluation_record_card_side_selection_bar_factory.dart

@@ -0,0 +1,12 @@
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+import 'package:luojigou_thinking_core/src/view/SideSelectionBar/i_side_selection_bar.dart';
+import '../i_side_selection_bar_factory.dart';
+import 'evaluation_record_card_side_selection_bar.dart';
+
+class EvaluationRecordCardSideSelectionBarFactory with ISideSelectionBarFactory {
+  @override
+  ISideSelectionBar getSideSelectionBar(List<AbilitySelectionTargetModel> dataList, Function(int selectIndex) selectAction) {
+    // TODO: implement getSideSelectionBar
+    return EvaluationRecordCardSideSelectionBar(dataList: dataList, selectAction: selectAction);
+  }
+}

+ 6 - 0
lib/src/view/SideSelectionBar/i_side_selection_bar.dart

@@ -0,0 +1,6 @@
+import 'package:luojigou_thinking_core/src/widget/widget.dart';
+import 'package:flutter/material.dart';
+
+mixin ISideSelectionBar {
+  Widget getSideSelectionBar();
+}

+ 6 - 0
lib/src/view/SideSelectionBar/i_side_selection_bar_factory.dart

@@ -0,0 +1,6 @@
+import 'i_side_selection_bar.dart';
+import 'package:luojigou_thinking_core/src/model/ability_selection_target_model.dart';
+
+mixin ISideSelectionBarFactory{
+  ISideSelectionBar getSideSelectionBar(List<AbilitySelectionTargetModel> dataList, Function(int selectIndex) selectAction);
+}

+ 11 - 0
lib/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame.dart

@@ -0,0 +1,11 @@
+import 'package:flutter/src/widgets/framework.dart';
+import '../abstract/i_bulletf_rame.dart';
+import 'ability_selection_bulletf_rame_view.dart';
+
+class AbilitySelectionBulletfRame implements IBulletfRame {
+  @override
+  Widget createBulletfRame() {
+    // TODO: implement createBulletfRame
+    return AbilitySelectionBulletfRameView();
+  }
+}

+ 10 - 0
lib/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame_color.dart

@@ -0,0 +1,10 @@
+import 'dart:ui';
+import '../abstract/i_bulletf_rame_color.dart';
+
+class AbilitySelectionBulletfRameColor implements IBulletfRameColor{
+  @override
+  Color getBulletfRameBarrierColor() {
+    // TODO: implement getBulletfRameBarrierColor
+    return Color(0xFF454E5F).withOpacity(0.31);
+  }
+}

+ 20 - 0
lib/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame_factory.dart

@@ -0,0 +1,20 @@
+import '../abstract/i_bulletf_rame_factory.dart';
+import '../abstract/i_bulletf_rame.dart';
+import '../abstract/i_bulletf_rame_color.dart';
+import 'ability_selection_bulletf_rame_color.dart';
+import 'ability_selection_bulletf_rame.dart';
+
+class AbilitySelectionBulletfRameFactory implements IBulletfRameFactory{
+  @override
+  IBulletfRame getBulletfRame() {
+    // TODO: implement getBulletfRame
+    return AbilitySelectionBulletfRame();
+  }
+
+  @override
+  IBulletfRameColor getBulletfRameColor() {
+    // TODO: implement getBulletfRameColor
+    return AbilitySelectionBulletfRameColor();
+  }
+
+}

+ 110 - 0
lib/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame_view.dart

@@ -0,0 +1,110 @@
+import 'package:flutter/material.dart';
+
+class AbilitySelectionBulletfRameView extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: Material(
+          color: Colors.transparent,
+          child: Stack(
+            children: <Widget>[
+              GestureDetector(
+                onTap: () {
+                  Navigator.pop(context);
+                },
+              ),
+              _activateWindow(context)
+            ],
+          )),
+    );
+  }
+
+  Widget _activateWindow(BuildContext context) {
+    return Center(
+      child: SizedBox(
+        width: MediaQuery.of(context).size.width - 30,
+        child: GestureDetector(
+          behavior: HitTestBehavior.translucent,
+          onTap: () {
+            FocusScope.of(context).requestFocus(FocusNode());
+          },
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+
+            children: [
+              Container(
+                width: double.infinity,
+                padding: EdgeInsets.symmetric(horizontal: 16),
+                decoration: BoxDecoration(
+                  color: Colors.white,
+                  borderRadius: BorderRadius.circular(30),
+                ),
+                child: Column(
+                  mainAxisSize: MainAxisSize.min,
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    SizedBox(height: 30),
+                    Row(
+                      children: [
+                        SizedBox(width: 2),
+                        Image.asset("assets/thinking_core/ability_selection.png", width: 34, height: 34),
+                        SizedBox(width: 9),
+                        Text("选择能力", style: TextStyle(fontSize: 20, height: 1, color: Color(0xFF333333), fontWeight: FontWeight.w500)),
+                      ],
+                    ),
+                    SizedBox(height: 30),
+                    ConstrainedBox(
+                      // BoxConstraints 构造
+                      constraints: BoxConstraints(
+                        minHeight: 100,
+                        maxHeight: (MediaQuery.of(context).size.width - 75) / 2 * 70 / 164.5 * (MediaQuery.of(context).padding.bottom != 0 ? 5 : 4) + (MediaQuery.of(context).padding.bottom != 0 ? 40 : 50),
+                        minWidth: 0,
+                        maxWidth: double.infinity,
+                      ),
+
+                      child: MediaQuery.removePadding(
+                        removeTop: true,
+                        context: context,
+                        child: GridView.builder(
+                            shrinkWrap: true,
+                            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+                                crossAxisCount: 2, //横轴三个子widget
+                                mainAxisSpacing: 10,
+                                crossAxisSpacing: 13,
+                                childAspectRatio: 164.5 / 70 //宽高比为1时,子widget
+                                ),
+                            itemCount: 10,
+                            itemBuilder: (_, index) {
+                              return Container(
+                                child: Stack(
+                                  alignment: Alignment.centerLeft,
+                                  children: [
+                                    Image.asset("assets/thinking_core/ability_bg${index % 5 + 1}.png"),
+                                    Padding(padding: EdgeInsets.only(left: 15), child: Text("观察能力", style: TextStyle(fontSize: 20, color: Color(0xFFFFFFFF), fontFamily: "YouSheBiaoTiHei"))),
+                                  ],
+                                ),
+                              );
+                            }),
+                      ),
+                    ),
+                    SizedBox(height: 50),
+                  ],
+                ),
+              ),
+              GestureDetector(
+                onTap: (){
+                  Navigator.pop(context);
+                },
+                child: Container(
+                  padding: EdgeInsets.all(16),
+                  color: Colors.transparent,
+                  child: Image.asset("assets/thinking_core/camera_close.png", width: 30, height: 30),
+                ),
+              ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}

+ 6 - 0
lib/src/view/bulletf_rame/abstract/i_bulletf_rame.dart

@@ -0,0 +1,6 @@
+import 'package:flutter/cupertino.dart';
+import 'package:luojigou_thinking_core/src/data/data_management.dart';
+
+mixin IBulletfRame{
+  Widget createBulletfRame();
+}

+ 5 - 0
lib/src/view/bulletf_rame/abstract/i_bulletf_rame_color.dart

@@ -0,0 +1,5 @@
+import 'dart:ui';
+
+mixin IBulletfRameColor{
+  Color getBulletfRameBarrierColor();
+}

+ 21 - 0
lib/src/view/bulletf_rame/abstract/i_bulletf_rame_factory.dart

@@ -0,0 +1,21 @@
+import 'package:flutter/material.dart';
+import 'i_bulletf_rame_color.dart';
+import 'i_bulletf_rame.dart';
+
+mixin IBulletfRameFactory {
+  IBulletfRame getBulletfRame();
+  IBulletfRameColor getBulletfRameColor();
+}
+
+class ActivateRouter<T> extends PageRouteBuilder<T> {
+  final Widget page;
+  final Color color;
+
+  ActivateRouter(this.page, this.color)
+      : super(
+          opaque: false,
+          barrierColor: color,
+          pageBuilder: (context, animation, secondaryAnimation) => page,
+          transitionsBuilder: (context, animation, secondaryAnimation, child) => child,
+        );
+}

+ 11 - 0
lib/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame.dart

@@ -0,0 +1,11 @@
+import 'package:flutter/src/widgets/framework.dart';
+import '../abstract/i_bulletf_rame.dart';
+import 'album_selection_bulletf_rame_view.dart';
+
+class AlbumSelectionBulletfRame implements IBulletfRame {
+  @override
+  Widget createBulletfRame() {
+    // TODO: implement createBulletfRame
+    return AlbumSelectionBulletfRameView();
+  }
+}

+ 10 - 0
lib/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame_color.dart

@@ -0,0 +1,10 @@
+import 'dart:ui';
+import '../abstract/i_bulletf_rame_color.dart';
+
+class AlbumSelectionBulletfRameColor implements IBulletfRameColor{
+  @override
+  Color getBulletfRameBarrierColor() {
+    // TODO: implement getBulletfRameBarrierColor
+    return Color(0xFF454E5F).withOpacity(0.31);
+  }
+}

+ 20 - 0
lib/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame_factory.dart

@@ -0,0 +1,20 @@
+import '../abstract/i_bulletf_rame_factory.dart';
+import '../abstract/i_bulletf_rame.dart';
+import '../abstract/i_bulletf_rame_color.dart';
+import 'album_selection_bulletf_rame.dart';
+import 'album_selection_bulletf_rame_color.dart';
+
+class AlbumSelectionBulletfRameFactory implements IBulletfRameFactory{
+  @override
+  IBulletfRame getBulletfRame() {
+    // TODO: implement getBulletfRame
+    return AlbumSelectionBulletfRame();
+  }
+
+  @override
+  IBulletfRameColor getBulletfRameColor() {
+    // TODO: implement getBulletfRameColor
+    return AlbumSelectionBulletfRameColor();
+  }
+
+}

+ 204 - 0
lib/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame_view.dart

@@ -0,0 +1,204 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+/// 相册选择
+class AlbumSelectionBulletfRameView extends StatefulWidget {
+  @override
+  AlbumSelectionBulletfRameViewState createState() => new AlbumSelectionBulletfRameViewState();
+}
+
+class AlbumSelectionBulletfRameViewState extends State<AlbumSelectionBulletfRameView> {
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: Material(
+          color: Colors.transparent,
+          child: Stack(
+            children: <Widget>[
+              GestureDetector(
+                onTap: () {
+                  Navigator.pop(context);
+                },
+              ),
+              _activateWindow(context)
+            ],
+          )),
+    );
+  }
+
+  Widget _activateWindow(BuildContext context) {
+    return Center(
+      child: SizedBox(
+        width: MediaQuery.of(context).size.width - 30,
+        child: GestureDetector(
+          behavior: HitTestBehavior.translucent,
+          onTap: () {
+            FocusScope.of(context).requestFocus(FocusNode());
+          },
+          child: Container(
+            width: double.infinity,
+            padding: EdgeInsets.only(left: 18),
+            decoration: BoxDecoration(
+              color: Colors.white,
+              borderRadius: BorderRadius.circular(30),
+            ),
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SizedBox(height: 30),
+                Row(
+                  children: [
+                    Image.asset("assets/thinking_core/camera.png", width: 34, height: 34),
+                    SizedBox(width: 9),
+                    Text("记录幼儿照片", style: TextStyle(fontSize: 20, height: 1, color: Color(0xFF333333), fontWeight: FontWeight.w500)),
+                  ],
+                ),
+                SizedBox(height: 30),
+                Container(
+                  height: 111,
+                  child: ListView.separated(
+                      scrollDirection: Axis.horizontal,
+                      itemBuilder: (context, index) {
+                        return index == 0
+                            ? Container(
+                                width: 111,
+                                height: 111,
+                                decoration: BoxDecoration(
+                                  color: Colors.white,
+                                  borderRadius: BorderRadius.circular(10),
+                                  border: Border.all(color: Color(0xFFBFBFBF), width: 0.56),
+                                ),
+                                child: Icon(
+                                  Icons.add,
+                                  color: Color(0xFF999999),
+                                ),
+                              )
+                            : Container(
+                                width: 111,
+                                height: 111,
+                                decoration: BoxDecoration(
+                                  color: Colors.white,
+                                  borderRadius: BorderRadius.circular(10),
+                                  border: Border.all(color: Color(0xFFBFBFBF), width: 0.56),
+                                ),
+                                child: Stack(
+                                  children: [
+                                    ClipRRect(
+                                      borderRadius: BorderRadius.circular(10),
+                                      child: Image.asset(
+                                        "assets/image_header.png",
+                                        fit: BoxFit.cover,
+                                      ),
+                                    ),
+                                    Positioned(
+                                      top: 2,
+                                      right: 2,
+                                      child: Image.asset("assets/thinking_core/camera_close.png", width: 22, height: 22),
+                                    )
+                                  ],
+                                ));
+                      },
+                      separatorBuilder: (_, __) {
+                        return SizedBox(width: 10);
+                      },
+                      itemCount: 3),
+                ),
+                SizedBox(height: 40),
+                Text("成长故事(选填)", style: TextStyle(fontSize: 16, height: 1, color: Color(0xFF333333), fontWeight: FontWeight.w500)),
+                SizedBox(height: 16),
+                TextEditBoxView(),
+                SizedBox(height: 40),
+                Center(
+                  child: GestureDetector(
+                    onTap: () {
+                      Navigator.pop(context);
+                    },
+                    child: Container(
+                      width: 133,
+                      height: 42,
+                      alignment: Alignment.center,
+                      decoration: BoxDecoration(
+                        borderRadius: BorderRadius.circular(21),
+                        border: Border.all(color: Color(0xFF6AA5FF), width: 1),
+                      ),
+                      child: Text("确定", style: TextStyle(fontSize: 16, height: 18 / 16, color: Color(0xFF5F87F0), fontWeight: FontWeight.w500)),
+                    ),
+                  ),
+                ),
+                SizedBox(height: 40),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+//文本编辑框
+class TextEditBoxView extends StatefulWidget {
+  @override
+  State<TextEditBoxView> createState() => _TextEditBoxViewState();
+}
+
+class _TextEditBoxViewState extends State<TextEditBoxView> {
+  late TextEditingController _controller;
+  late int _number;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _controller = TextEditingController();
+    _number = 0;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      height: 138,
+      width: double.infinity,
+      margin: EdgeInsets.only(right: 18),
+      padding: EdgeInsets.only(left: 13, right: 12, bottom: 12, top: 14),
+      decoration: BoxDecoration(
+        color: Color(0xFFF3F5F7),
+        borderRadius: BorderRadius.circular(10),
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.end,
+        children: [
+          Expanded(
+            child: TextField(
+                inputFormatters: [LengthLimitingTextInputFormatter(100)],
+                controller: _controller,
+                onChanged: (text) {
+                  _number = text.length;
+                },
+                autofocus: false,
+                scrollPadding: EdgeInsets.zero,
+                cursorColor: Colors.green,
+                decoration: InputDecoration(
+                    contentPadding: EdgeInsets.zero,
+                    isDense: true,
+                    border: InputBorder.none,
+                    hintText: '可以在这里输入教育建议,孩子表现行为的补充描述等',
+                    hintMaxLines: 5,
+                    hintStyle: TextStyle(
+                      fontSize: 14,
+                      height: 21 / 14,
+                      color: Color(0xFFC3C3C3),
+                    )),
+                maxLines: null,
+                style: TextStyle(
+                  fontSize: 14,
+                  height: 21 / 14,
+                  color: Colors.black,
+                )),
+          ),
+          Text("${_number}/100", style: TextStyle(fontSize: 12, height: 17 / 12, color: Color(0xFF666666), fontWeight: FontWeight.w400))
+        ],
+      ),
+    );
+  }
+}

+ 11 - 0
lib/src/view/bulletf_rame/customer/customer_bulletf_rame.dart

@@ -0,0 +1,11 @@
+import 'package:flutter/src/widgets/framework.dart';
+import 'customer_verify_bulletf_rame_view.dart';
+import '../abstract/i_bulletf_rame.dart';
+
+class CustomerBulletfRame implements IBulletfRame {
+  @override
+  Widget createBulletfRame() {
+    // TODO: implement createBulletfRame
+    return CustomerBulletfRameView();
+  }
+}

+ 10 - 0
lib/src/view/bulletf_rame/customer/customer_verify_bulletf_rame_color.dart

@@ -0,0 +1,10 @@
+import 'dart:ui';
+import '../abstract/i_bulletf_rame_color.dart';
+
+class CustomerBulletfRameColor implements IBulletfRameColor{
+  @override
+  Color getBulletfRameBarrierColor() {
+    // TODO: implement getBulletfRameBarrierColor
+    return Color(0xB3000000);
+  }
+}

+ 20 - 0
lib/src/view/bulletf_rame/customer/customer_verify_bulletf_rame_factory.dart

@@ -0,0 +1,20 @@
+import 'package:luojigou_thinking_core/src/data/data_management.dart';
+import '../abstract/i_bulletf_rame_factory.dart';
+import '../abstract/i_bulletf_rame.dart';
+import '../abstract/i_bulletf_rame_color.dart';
+import 'customer_bulletf_rame.dart';
+import 'customer_verify_bulletf_rame_color.dart';
+
+class CustomerBulletfRameFactory implements IBulletfRameFactory{
+  @override
+  IBulletfRame getBulletfRame() {
+    // TODO: implement getBulletfRame
+    return CustomerBulletfRame();
+  }
+
+  @override
+  IBulletfRameColor getBulletfRameColor() {
+    // TODO: implement getBulletfRameColor
+    return CustomerBulletfRameColor();
+  }
+}

+ 123 - 0
lib/src/view/bulletf_rame/customer/customer_verify_bulletf_rame_view.dart

@@ -0,0 +1,123 @@
+import 'package:flutter/material.dart';
+
+/// 客服弹框
+class CustomerBulletfRameView extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: Material(
+          color: Colors.transparent,
+          child: Stack(
+            children: <Widget>[
+              GestureDetector(
+                onTap: () {
+                  Navigator.pop(context);
+                },
+              ),
+              _activateWindow(context)
+            ],
+          )),
+    );
+  }
+
+  Widget _activateWindow(BuildContext context) {
+    return Center(
+      child: SizedBox(
+        width: MediaQuery.of(context).size.width - 36,
+        child: Container(
+          width: double.infinity,
+          decoration: BoxDecoration(
+            borderRadius: BorderRadius.circular(12),
+            gradient: LinearGradient(colors: [Color(0xFFB0C9FF), Color(0xFFFFFFFF)], begin: Alignment(0, -0.9), end: Alignment(0, -0.01)),
+          ),
+          child: Stack(
+            alignment: Alignment.center,
+            children: [
+              Column(
+                mainAxisSize: MainAxisSize.min,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  Image.asset("assets/thinking_core/customer_dog.png", width: 132, height: 126),
+                  SizedBox(height: 18),
+                  Text("您还未开通思维芯游戏测评", style: TextStyle(fontSize: 14, height: 20 / 14, color: Color(0xFF666666))),
+                  SizedBox(height: 6),
+                  Text.rich(TextSpan(children: [
+                    TextSpan(
+                      text: "请联系工作人员:",
+                      // textAlign: TextAlign.center,
+                      style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xFF666666), height: 23.5 / 14),
+                    ),
+                    WidgetSpan(
+                        child: GestureDetector(
+                          onTap: () {
+                            // launch("tel://+8617800151521");
+                          },
+                          child: Text(
+                            "010-59626411",
+                            style: TextStyle(fontSize: 14, height: 23.5 / 14, color: Color(0xFF5F87F0), fontWeight: FontWeight.w600),
+                          ),
+                        ))
+                  ])),
+                  SizedBox(height: 6),
+                  Text("或联系在线客服(请备注:发展评估)", style: TextStyle(fontSize: 14, height: 20 / 14, color: Color(0xFF666666))),
+                  SizedBox(height: 28),
+                  GestureDetector(
+                    onTap: () async {
+                      // bool install = await LJGWeiXinShareHelper.isInstalled();
+                      // if (!install) {
+                      //   LJGToastHelper.showText("请您安装微信");
+                      //   return;
+                      // }
+                      // launchWeChatMiniProgram(username: 'gh_fbe5ebf0c69e', path: '/pages/contact/index', miniProgramType: WXMiniProgramType.RELEASE);
+                    },
+                    child: Container(
+                      width: 171,
+                      height: 40,
+                      decoration: BoxDecoration(color: Color(0xFF5F87F0), borderRadius: BorderRadius.circular(20)),
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          SizedBox(width: 23),
+                          Image.asset(
+                            "assets/thinking_core/customer_wechat.png",
+                            width: 23,
+                            height: 18.5,
+                          ),
+                          SizedBox(width: 6),
+                          Text(
+                            "在线客服获取",
+                            style: TextStyle(fontSize: 16, height: 22.5 / 16, color: Color(0xFFFFFFFF), fontWeight: FontWeight.w500),
+                          ),
+                          SizedBox(width: 23)
+                        ],
+                      ),
+                    ),
+                  ),
+                  SizedBox(height: 30),
+                ],
+              ),
+              Positioned(
+                right: 0,
+                top: 0,
+                child: GestureDetector(
+                  onTap: () {
+                    Navigator.pop(context);
+                  },
+                  child: Container(
+                    padding: EdgeInsets.symmetric(horizontal: 20, vertical: 28),
+                    color: Colors.transparent,
+                    child: Image.asset(
+                      'assets/thinking_core/close_white.png',
+                      width: 13,
+                      height: 13,
+                    ),
+                  ),
+                ),
+              ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}

+ 11 - 0
lib/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame.dart

@@ -0,0 +1,11 @@
+import 'package:flutter/src/widgets/framework.dart';
+import 'policy_support_bulletf_rame_view.dart';
+import '../abstract/i_bulletf_rame.dart';
+
+class PolicySupportBulletfRame implements IBulletfRame {
+  @override
+  Widget createBulletfRame() {
+    // TODO: implement createBulletfRame
+    return PolicySupportBulletfRameView();
+  }
+}

+ 9 - 0
lib/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame_color.dart

@@ -0,0 +1,9 @@
+import 'dart:ui';
+import '../abstract/i_bulletf_rame_color.dart';
+class PolicySupportBulletfRameColor implements IBulletfRameColor{
+  @override
+  Color getBulletfRameBarrierColor() {
+    // TODO: implement getBulletfRameBarrierColor
+    return Color(0xCC000000);
+  }
+}

+ 20 - 0
lib/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame_factory.dart

@@ -0,0 +1,20 @@
+import '../abstract/i_bulletf_rame_factory.dart';
+import '../abstract/i_bulletf_rame.dart';
+import '../abstract/i_bulletf_rame_color.dart';
+import 'policy_support_bulletf_rame.dart';
+import 'policy_support_bulletf_rame_color.dart';
+
+class PolicySupportBulletfRameFactory implements IBulletfRameFactory{
+  @override
+  IBulletfRame getBulletfRame() {
+    // TODO: implement getBulletfRame
+    return PolicySupportBulletfRame();
+  }
+
+  @override
+  IBulletfRameColor getBulletfRameColor() {
+    // TODO: implement getBulletfRameColor
+    return PolicySupportBulletfRameColor();
+  }
+
+}

+ 129 - 0
lib/src/view/bulletf_rame/policy_support/policy_support_bulletf_rame_view.dart

@@ -0,0 +1,129 @@
+import 'package:flutter/material.dart';
+
+///策略支持弹框
+class PolicySupportBulletfRameView extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: Material(
+          color: Colors.transparent,
+          child: Stack(
+            children: <Widget>[
+              GestureDetector(
+                onTap: () {
+                  Navigator.pop(context);
+                },
+              ),
+              _activateWindow(context)
+            ],
+          )),
+    );
+  }
+
+  Widget _activateWindow(BuildContext context) {
+    return Center(
+      child: SizedBox(
+        width: MediaQuery.of(context).size.width - 36,
+        child: Container(
+          width: double.infinity,
+          decoration: BoxDecoration(
+            borderRadius: BorderRadius.circular(12),
+          ),
+          child: Stack(
+            alignment: Alignment.topCenter,
+            children: [
+              Image.asset("assets/thinking_core/strategy_bg.png"),
+              Positioned(top: 27, left: 0, right: 0, child: Image.asset("assets/thinking_core/policy_support.png")),
+              Positioned(
+                top: 109,
+                bottom: 35,
+                left: 22,
+                right: 22,
+                child: Column(
+                  children: [
+                    Padding(
+                      padding: EdgeInsets.only(left: 5, right: 10),
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Text("模式发展能力-反应程度", style: TextStyle(fontSize: 16, height: 22 / 16, color: Colors.white, fontWeight: FontWeight.w500)),
+                          Image.asset("assets/thinking_core/dog.png", width: 60, height: 50),
+                        ],
+                      ),
+                    ),
+                    Expanded(
+                      child: Container(
+                        decoration: BoxDecoration(color: Color(0xFFEBF0FE), borderRadius: BorderRadius.circular(20)),
+                        child: Column(
+                          children: [
+                            Container(
+                              height: 43,
+                              alignment: Alignment.center,
+                              child: Text("早期", style: TextStyle(fontSize: 16, height: 22 / 16, color: Color(0xFF4D66FF), fontWeight: FontWeight.w600)),
+                            ),
+                            Expanded(
+                                child: Container(
+                                  decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)),
+                                  child: ContentListView(),
+                                ))
+                          ],
+                        ),
+                      ),
+                    ),
+                    SizedBox(height: 20),
+                    GestureDetector(
+                      onTap: (){
+                        Navigator.pop(context);
+                      },
+                      child: Container(
+                        width: 153,
+                        height: 42,
+                        alignment: Alignment.center,
+                        decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(21)),
+                        child: Text("知道啦", style: TextStyle(fontSize: 16, height: 18 / 16, color: Color(0xFF5F87F0), fontWeight: FontWeight.w500)),
+                      ),
+                    )
+                  ],
+                ),
+              )
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class ContentListView extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return ListView.separated(
+        itemBuilder: (_, index) {
+          return Container(
+            margin: EdgeInsets.symmetric(horizontal: 13),
+            child: Column(
+              children: [
+                Row(
+                  children: [
+                    SizedBox(width: 3),
+                    Container(
+                      width: 4,
+                      height: 4,
+                      decoration: BoxDecoration(color: Color(0xFF4D66FF), borderRadius: BorderRadius.circular(2)),
+                    ),
+                    SizedBox(width: 6),
+                    Text("一日活动支持", style: TextStyle(fontSize: 14, height: 24 / 14, color: Color(0xFF4D66FF), fontFamily: "YouSheBiaoTiHei")),
+                  ],
+                ),
+                SizedBox(height: 1),
+                Padding(padding: EdgeInsets.only(left: 13), child: Text("提供机会让幼儿注意和描述自然界的模式(岩石、天空、树叶或贝壳的模式", style: TextStyle(fontSize: 12, height: 21 / 12, color: Color(0xFF333333)))),
+              ],
+            ),
+          );
+        },
+        separatorBuilder: (_, index) {
+          return SizedBox(height: 20);
+        },
+        itemCount: 9);
+  }
+}

+ 11 - 0
lib/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame.dart

@@ -0,0 +1,11 @@
+import 'package:flutter/src/widgets/framework.dart';
+import 'report_generation_bulletf_rame_view.dart';
+import '../abstract/i_bulletf_rame.dart';
+
+class ReportGenerationBulletfRame implements IBulletfRame {
+  @override
+  Widget createBulletfRame() {
+    // TODO: implement createBulletfRame
+    return ReportGenerationBulletfRameView();
+  }
+}

+ 9 - 0
lib/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame_color.dart

@@ -0,0 +1,9 @@
+import 'dart:ui';
+import '../abstract/i_bulletf_rame_color.dart';
+class ReportGenerationBulletfRameColor implements IBulletfRameColor{
+  @override
+  Color getBulletfRameBarrierColor() {
+    // TODO: implement getBulletfRameBarrierColor
+    return Color(0xFF000000).withOpacity(0.6);
+  }
+}

+ 20 - 0
lib/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame_factory.dart

@@ -0,0 +1,20 @@
+import '../abstract/i_bulletf_rame_factory.dart';
+import '../abstract/i_bulletf_rame.dart';
+import '../abstract/i_bulletf_rame_color.dart';
+import 'report_generation_bulletf_rame.dart';
+import 'report_generation_bulletf_rame_color.dart';
+
+class ReportGenerationBulletfRameFactory implements IBulletfRameFactory{
+  @override
+  IBulletfRame getBulletfRame() {
+    // TODO: implement getBulletfRame
+    return ReportGenerationBulletfRame();
+  }
+
+  @override
+  IBulletfRameColor getBulletfRameColor() {
+    // TODO: implement getBulletfRameColor
+    return ReportGenerationBulletfRameColor();
+  }
+
+}

+ 52 - 0
lib/src/view/bulletf_rame/report_generation/report_generation_bulletf_rame_view.dart

@@ -0,0 +1,52 @@
+import 'package:flutter/material.dart';
+
+/// 报告生成加载框
+class ReportGenerationBulletfRameView extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: Material(
+          color: Colors.transparent,
+          child: Stack(
+            children: <Widget>[
+              GestureDetector(
+                onTap: () {
+                  Navigator.pop(context);
+                },
+              ),
+              _activateWindow(context)
+            ],
+          )),
+    );
+  }
+
+  Widget _activateWindow(BuildContext context) {
+    return Center(
+      child: SizedBox(
+        width: MediaQuery.of(context).size.width - 70,
+        child: Container(
+          width: double.infinity,
+          decoration: BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.circular(20),
+          ),
+          child: Stack(
+            alignment: Alignment.topCenter,
+            children: [
+              Image.asset("assets/thinking_core/report_generation_bg.png"),
+              Column(
+                mainAxisSize: MainAxisSize.min,
+                children: [
+                  SizedBox(height: 35.5),
+                  Image.asset("assets/thinking_core/dog_report.png", width: 149, height: 133),
+                  SizedBox(height: 18.5),
+                  Text("学期综合发展评估生成中……", style: TextStyle(fontSize: 17, height: 24 / 17, color: Color(0xFF666666), fontWeight:FontWeight.w500)),
+                ],
+              ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}

+ 6 - 0
lib/src/view/bulletf_rame/verify/commit_verify_bulletf_rame_view.dart

@@ -0,0 +1,6 @@
+import 'verify_bulletf_rame_view.dart';
+
+/// 提交确认弹框
+class CommitVerifyBulletfRameView extends VerifyBulletfRameView {
+  const CommitVerifyBulletfRameView() : super(title: " 确认提交?", content: "提交后不支持修改");
+}

+ 6 - 0
lib/src/view/bulletf_rame/verify/exit_verify_bulletf_rame_view.dart

@@ -0,0 +1,6 @@
+import 'verify_bulletf_rame_view.dart';
+
+/// 退出确认弹框
+class ExitVerifyBulletfRameView extends VerifyBulletfRameView {
+  const ExitVerifyBulletfRameView() : super(title: " 确认要退出记录?", content: "退出后本次记录会自动保存");
+}

+ 17 - 0
lib/src/view/bulletf_rame/verify/verify_bulletf_rame.dart

@@ -0,0 +1,17 @@
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:luojigou_thinking_core/src/data/data_management.dart';
+import '../abstract/i_bulletf_rame.dart';
+import 'commit_verify_bulletf_rame_view.dart';
+import 'exit_verify_bulletf_rame_view.dart';
+
+class VerifyBulletfRame implements IBulletfRame {
+  final VerifyType verifyType;
+
+  VerifyBulletfRame(this.verifyType);
+
+  @override
+  Widget createBulletfRame() {
+    // TODO: implement createBulletfRame
+    return verifyType == VerifyType.Commit ? CommitVerifyBulletfRameView() : ExitVerifyBulletfRameView();
+  }
+}

+ 10 - 0
lib/src/view/bulletf_rame/verify/verify_bulletf_rame_color.dart

@@ -0,0 +1,10 @@
+import 'dart:ui';
+import '../abstract/i_bulletf_rame_color.dart';
+
+class VerifyBulletfRameColor implements IBulletfRameColor{
+  @override
+  Color getBulletfRameBarrierColor() {
+    // TODO: implement getBulletfRameBarrierColor
+    return Color(0xCC000000);
+  }
+}

+ 24 - 0
lib/src/view/bulletf_rame/verify/verify_bulletf_rame_factory.dart

@@ -0,0 +1,24 @@
+import 'package:luojigou_thinking_core/src/data/data_management.dart';
+import '../abstract/i_bulletf_rame_factory.dart';
+import '../abstract/i_bulletf_rame.dart';
+import '../abstract/i_bulletf_rame_color.dart';
+import 'verify_bulletf_rame_color.dart';
+import 'verify_bulletf_rame.dart';
+
+class VerifyBulletfRameFactory implements IBulletfRameFactory{
+  final VerifyType verifyType;
+  VerifyBulletfRameFactory(this.verifyType);
+
+  @override
+  IBulletfRame getBulletfRame() {
+    // TODO: implement getBulletfRame
+    return VerifyBulletfRame(verifyType);
+  }
+
+  @override
+  IBulletfRameColor getBulletfRameColor() {
+    // TODO: implement getBulletfRameColor
+    return VerifyBulletfRameColor();
+  }
+
+}

+ 92 - 0
lib/src/view/bulletf_rame/verify/verify_bulletf_rame_view.dart

@@ -0,0 +1,92 @@
+import 'package:flutter/material.dart';
+
+/// 确认弹框
+abstract class VerifyBulletfRameView extends StatelessWidget {
+  final String title;
+  final String content;
+
+  const VerifyBulletfRameView({Key? key, required this.title, required this.content}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: Material(
+          color: Colors.transparent,
+          child: Stack(
+            children: <Widget>[
+              GestureDetector(
+                onTap: () {
+                  Navigator.pop(context);
+                },
+              ),
+              _activateWindow(context)
+            ],
+          )),
+    );
+  }
+
+  Widget _activateWindow(BuildContext context) {
+    return Center(
+      child: SizedBox(
+        width: MediaQuery.of(context).size.width - 80,
+        child: Container(
+          width: double.infinity,
+          decoration: BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.circular(20),
+          ),
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              SizedBox(height: 30),
+              Text(title, textAlign: TextAlign.center, style: TextStyle(fontSize: 18, height: 1, color: Color(0xFF333333), fontWeight: FontWeight.w500)),
+              SizedBox(height: 14),
+              Text(content, textAlign: TextAlign.center, style: TextStyle(fontSize: 18, height: 1, color: Color(0xFF333333), fontWeight: FontWeight.w500)),
+              SizedBox(height: 33),
+              Padding(
+                padding: EdgeInsets.symmetric(horizontal: 29),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    GestureDetector(
+                      onTap: () async {
+                        Navigator.pop(context);
+                      },
+                      child: Container(
+                        width: 113,
+                        height: 42,
+                        alignment: Alignment.center,
+                        decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), border: Border.all(color: Color(0x99999999), width: 1)),
+                        child: Text(
+                          "取消",
+                          style: TextStyle(fontSize: 16, height: 18 / 16, color: Color(0xFF666666), fontWeight: FontWeight.w500),
+                        ),
+                      ),
+                    ),
+                    GestureDetector(
+                      onTap: () async {
+                        Navigator.of(context)..pop()..pop();
+                      },
+                      child: Container(
+                        width: 113,
+                        height: 42,
+                        alignment: Alignment.center,
+                        decoration: BoxDecoration(color: Color(0xFF5F87F0), borderRadius: BorderRadius.circular(20)),
+                        child: Text(
+                          "确认",
+                          style: TextStyle(fontSize: 16, height: 18 / 16, color: Color(0xFFFFFFFF), fontWeight: FontWeight.w500),
+                        ),
+                      ),
+                    )
+                  ],
+                ),
+              ),
+              SizedBox(height: 20),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}

+ 166 - 0
lib/src/view/degree_of_exploration_content_widget.dart

@@ -0,0 +1,166 @@
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/src/view/student_select_grade/student_select_grade.dart';
+// import 'package:luojigou_thinking_core/src/view/student_select_grade/student_select_grade.dart';
+
+class DegreeOfExplorationContentWidget extends StatefulWidget {
+
+  const DegreeOfExplorationContentWidget({Key? key}) : super(key: key);
+
+  @override
+  DegreeOfExplorationContentWidgetState createState() => new DegreeOfExplorationContentWidgetState();
+}
+
+class DegreeOfExplorationContentWidgetState extends State<DegreeOfExplorationContentWidget> with AutomaticKeepAliveClientMixin {
+  late int students; //学生总数
+  late List<StudentSelectItems> _studentsItemsList;
+
+  late PageController _controller;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _controller = PageController();
+
+    students = 30;
+    _studentsItemsList = [];
+
+    for (int i = 0; i < (students / 12).ceil(); i++) {
+      if (i == (students / 12).ceil() - 1 && students % 12 > 0) {
+        _studentsItemsList.add(StudentSelectItems(count: students % 12));
+      } else {
+        _studentsItemsList.add(StudentSelectItems(count: 12));
+      }
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Container(
+          height: 179,
+          child: PageView(
+            controller: _controller,
+            scrollDirection: Axis.horizontal,
+            pageSnapping: true,
+            children: _studentsItemsList,
+          ),
+        ),
+        SizedBox(height: 6),
+        DotsIndicator(
+          controller: _controller,
+          itemCount: (students / 12).ceil(),
+          color: Color(0xFFD9E7FF),
+          // onPageSelected: (int page) {
+          //   _controller.animateToPage(page, duration: Duration(milliseconds: 300), curve: Curves.ease);
+          // },
+        ),
+        SizedBox(height: 25)
+      ],
+    );
+  }
+
+  @override
+  // TODO: implement wantKeepAlive
+  bool get wantKeepAlive => true;
+}
+
+class StudentSelectItems extends StatelessWidget {
+  final int count;
+
+  const StudentSelectItems({Key? key, required this.count}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return GridView.builder(
+        physics: NeverScrollableScrollPhysics(),
+        padding: EdgeInsets.only(left: 18, top: 21, bottom: 37, right: 18),
+        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 6, mainAxisSpacing: 16, crossAxisSpacing: (MediaQuery.of(context).size.width - 252) / 5, childAspectRatio: 36 / 71),
+        itemCount: count,
+        itemBuilder: (_, index) {
+          return StudentSlectGrade(grade: '早期', isSelect: true);
+        });
+  }
+}
+
+/// An indicator showing the currently selected page of a PageController
+class DotsIndicator extends AnimatedWidget {
+  DotsIndicator({
+    required this.controller,
+    required this.itemCount,
+    this.onPageSelected,
+    this.color: Colors.white,
+  }) : super(listenable: controller);
+
+  /// The PageController that this DotsIndicator is representing.
+  final PageController controller;
+
+  /// The number of items managed by the PageController
+  final int itemCount;
+
+  /// Called when a dot is tapped
+  final ValueChanged<int>? onPageSelected;
+
+  /// The color of the dots.
+  ///
+  /// Defaults to `Colors.white`.
+  final Color color;
+
+  // The base size of the dots
+  static const double _kDotSize = 4.0;
+
+  // The increase in the size of the selected dot
+  static const double _kMaxZoom = 2.0;
+
+  // The distance between the center of each dot
+  static const double _kDotSpacing = 25.0;
+
+  Widget _buildDot(int index, int pageCount) {
+    // 当前位置
+    double currentPosition = ((controller.page ?? controller.initialPage.toDouble()) % pageCount.toDouble());
+
+    // 计算变化曲线
+    double selectedness = Curves.easeOut.transform(
+      max(
+        0.0,
+        1.0 - (currentPosition - index).abs(),
+      ),
+    );
+
+    // 从0点跳到最后一个时状态需要特殊处理
+    if (currentPosition > pageCount - 1 && index == 0) {
+      selectedness = 1 - (pageCount.toDouble() - currentPosition);
+    }
+
+    // 计算缩放大小
+    double zoom = 1.0 + (_kMaxZoom - 1.0) * selectedness;
+    return new Container(
+      width: _kDotSpacing,
+      child: new Center(
+        child: new Material(
+          color: color,
+          type: MaterialType.circle,
+          child: new Container(
+            width: _kDotSize * zoom,
+            height: _kDotSize * zoom,
+            child: new InkWell(
+                // onTap: () => onPageSelected(index),
+                ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  Widget build(BuildContext context) {
+    return new Row(
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: new List<Widget>.generate(itemCount, (int index) {
+        return _buildDot(index, itemCount);
+      }),
+    );
+  }
+}

+ 105 - 0
lib/src/view/degree_of_exploration_widget.dart

@@ -0,0 +1,105 @@
+import 'package:flutter/material.dart';
+
+/* 早中后期选择按钮 */
+class DegreeOfExplorationWidget extends StatefulWidget {
+  final List<DegreeOfExplorationModel> dataList;
+  final ValueNotifier<int> notifier;
+
+  const DegreeOfExplorationWidget({Key? key, required this.dataList, required this.notifier}) : super(key: key);
+
+  @override
+  DegreeOfExplorationWidgetState createState() => new DegreeOfExplorationWidgetState();
+}
+
+class DegreeOfExplorationWidgetState extends State<DegreeOfExplorationWidget> {
+  late int _selectIndex;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _selectIndex = widget.notifier.value;
+    widget.dataList[_selectIndex].isSelected = true;
+    widget.notifier.addListener(() {
+      if (_selectIndex != widget.notifier.value) {
+        _selectIndex = widget.notifier.value;
+        selectButtonAction(widget.dataList[_selectIndex]);
+      }
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      height: 32,
+      margin: EdgeInsets.symmetric(horizontal: 18.0),
+      decoration: BoxDecoration(color: Color(0xFFFCFBFD), borderRadius: BorderRadius.circular(16)),
+      child: Row(
+        children: List.generate(widget.dataList.length, (index) => Expanded(child: SelectButton(widget.dataList[index], index))),
+      ),
+    );
+  }
+
+  Widget SelectButton(DegreeOfExplorationModel buttonDataModel, int index) {
+    return GestureDetector(
+      onTap: () {
+        selectButtonAction(buttonDataModel);
+        widget.notifier.value = index;
+      },
+      child: Container(
+        decoration: BoxDecoration(color: buttonDataModel.isSelected ? Color(0xFF5F87F0) : Colors.transparent, borderRadius: BorderRadius.circular(16)),
+        child: Align(
+          alignment: Alignment.center,
+          child: Text(
+            buttonDataModel.title,
+            style: TextStyle(fontSize: 12, height: 14 / 12, color: buttonDataModel.isSelected ? Colors.white : Color(0xFF8B8B8B), fontWeight: FontWeight.w600),
+          ),
+        ),
+      ),
+    );
+  }
+
+  void selectButtonAction(DegreeOfExplorationModel buttonDataModel) {
+    if (!mounted) return;
+    setState(() {
+      for (var model in widget.dataList) {
+        model.isSelected = false;
+        if (model.title == buttonDataModel.title) {
+          model.isSelected = true;
+        }
+      }
+    });
+  }
+}
+
+class DegreeOfExplorationModel {
+  final String title;
+  bool isSelected;
+  DegreeOfExplorationModel({required this.title, required this.isSelected});
+}
+
+
+// examples:
+/*
+  List<DegreeOfExplorationModel> dataList = [
+    DegreeOfExplorationModel(title: "探索 早期", isSelected: false),
+    DegreeOfExplorationModel(title: "探索 中期", isSelected: false),
+    DegreeOfExplorationModel(title: "探索 后期", isSelected: false),
+    DegreeOfExplorationModel(title: "探索 中后期", isSelected: false)
+  ];
+
+  ValueNotifier<int> _notifier;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+    _notifier = ValueNotifier(1);
+    _notifier.addListener(() {
+      print("切换卡片Index");
+      print(_notifier.value);
+    });
+  }
+
+* */

部分文件因为文件数量过多而无法显示