Browse Source

[new]增加tab&首页显示

zk 1 year ago
parent
commit
d08614103a

BIN
assets/images/icon_charge.webp


BIN
assets/images/icon_charge_arrow.webp


BIN
assets/images/icon_charge_txt.webp


BIN
assets/images/icon_home_logged.webp


+ 7 - 0
assets/string/base/string.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">电子秘书</string>
+    <string name="main_tab_home">首页</string>
+    <string name="main_tab_file">文件</string>
+    <string name="home_go_login">立即登录</string>
+</resources>

+ 3 - 1
lib/base/base_page.dart

@@ -1,6 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:get/get.dart';
 
 
+import '../resource/colors.gen.dart';
+
 abstract class BasePage<T extends GetxController> extends GetView<T> {
 abstract class BasePage<T extends GetxController> extends GetView<T> {
   const BasePage({super.key});
   const BasePage({super.key});
 
 
@@ -15,6 +17,6 @@ abstract class BasePage<T extends GetxController> extends GetView<T> {
   Widget? buildBody(BuildContext context);
   Widget? buildBody(BuildContext context);
 
 
   Color backgroundColor() {
   Color backgroundColor() {
-    return const Color(0xFF1A1A1A);
+    return ColorName.bgColorPrimary;
   }
   }
 }
 }

+ 4 - 0
lib/module/home/controller.dart

@@ -0,0 +1,4 @@
+import 'package:electronic_assistant/base/base_controller.dart';
+import 'package:get/get.dart';
+
+class HomePageController extends BaseController {}

+ 137 - 0
lib/module/home/view.dart

@@ -0,0 +1,137 @@
+import 'package:electronic_assistant/base/base_page.dart';
+import 'package:electronic_assistant/resource/assets.gen.dart';
+import 'package:electronic_assistant/resource/colors.gen.dart';
+import 'package:electronic_assistant/resource/string.gen.dart';
+import 'package:electronic_assistant/utils/expand.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+
+import 'controller.dart';
+
+class HomePage extends BasePage<HomePageController> {
+  const HomePage({super.key});
+
+  @override
+  Widget? buildBody(BuildContext context) {
+    return Stack(
+      children: [
+        buildBgBox(),
+        buildTopGradient(),
+        SafeArea(
+          child: Column(
+            children: [
+              Container(
+                width: 1.sw,
+                padding: const EdgeInsets.all(12).w,
+                child: buildOperationBar(),
+              ),
+              Expanded(
+                  child: CustomScrollView(
+                slivers: [
+                  SliverToBoxAdapter(
+                    child: Container(
+                      padding: EdgeInsets.all(16),
+                      color: Colors.blue,
+                      child: Text('头部', style: TextStyle(color: Colors.white)),
+                    ),
+                  ),
+                  SliverList(
+                    delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                        return ListTile(
+                          title: Text('Item $index'),
+                        );
+                      },
+                      childCount: 20, // 列表项的数量
+                    ),
+                  ),
+                  SliverToBoxAdapter(
+                    child: Container(
+                      padding: EdgeInsets.all(16),
+                      color: Colors.green,
+                      child: Text('尾部', style: TextStyle(color: Colors.white)),
+                    ),
+                  ),
+                ],
+              ))
+            ],
+          ),
+        )
+      ],
+    );
+  }
+
+  Row buildOperationBar() {
+    return Row(children: [
+      GestureDetector(
+        onTap: () {},
+        child: Row(
+          children: [
+            SizedBox(
+                width: 0.1.sw,
+                height: 0.1.sw,
+                child: Assets.images.iconHomeLogged.image()),
+            SizedBox(width: 8.w),
+            Text(StringName.homeGoLogin.tr,
+                style: TextStyle(
+                    fontWeight: FontWeight.bold,
+                    fontSize: 15.sp,
+                    color: ColorName.commonTxtColor))
+          ],
+        ),
+      ),
+      const Spacer(),
+      GestureDetector(
+          child: DecoratedBox(
+              decoration: BoxDecoration(
+                color: Colors.white,
+                borderRadius: BorderRadius.circular(16),
+              ),
+              child: Padding(
+                padding:
+                    const EdgeInsets.symmetric(horizontal: 8, vertical: 2).w,
+                child: Row(
+                  children: [
+                    SizedBox(
+                        width: 28.w,
+                        height: 28.w,
+                        child: Assets.images.iconCharge.image()),
+                    SizedBox(width: 4.w),
+                    SizedBox(
+                        width: 28.w,
+                        child: Assets.images.iconChargeTxt.image()),
+                    SizedBox(
+                        width: 12.w,
+                        height: 12.w,
+                        child: Assets.images.iconChargeArrow.image()),
+                  ],
+                ),
+              )),
+          onTap: () {})
+    ]);
+  }
+
+  Container buildTopGradient() {
+    return Container(
+        width: 1.sw,
+        height: 0.4444444444444444.sw,
+        decoration: BoxDecoration(
+          gradient: LinearGradient(
+            colors: ['#E8EBFF'.toColor(), '#00E8EBFF'.toColor()],
+            begin: Alignment.topCenter,
+            end: Alignment.bottomCenter,
+            stops: const [0.3, 1.0],
+          ),
+        ) // 其他子小部件
+        );
+  }
+
+  DecoratedBox buildBgBox() {
+    return DecoratedBox(
+        decoration: BoxDecoration(color: '#F6F6F6'.toColor()),
+        child: Container(
+          height: double.infinity,
+        ));
+  }
+}

+ 3 - 2
lib/module/main/controller.dart

@@ -3,6 +3,7 @@ import 'dart:ui';
 import 'package:electronic_assistant/base/base_controller.dart';
 import 'package:electronic_assistant/base/base_controller.dart';
 import 'package:electronic_assistant/resource/assets.gen.dart';
 import 'package:electronic_assistant/resource/assets.gen.dart';
 import 'package:electronic_assistant/resource/colors.gen.dart';
 import 'package:electronic_assistant/resource/colors.gen.dart';
+import 'package:electronic_assistant/resource/string.gen.dart';
 import 'package:electronic_assistant/utils/expand.dart';
 import 'package:electronic_assistant/utils/expand.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:get/get.dart';
 import 'package:get/get.dart';
@@ -10,13 +11,13 @@ import 'package:get/get.dart';
 class MainController extends BaseController {
 class MainController extends BaseController {
   final List<TabBean> tabBeans = [
   final List<TabBean> tabBeans = [
     TabBean(
     TabBean(
-        'main_tab_home'.tr,
+        StringName.mainTabHome,
         Assets.images.mainTabHomeUnSelect.path,
         Assets.images.mainTabHomeUnSelect.path,
         Assets.images.mainTabHomeSelected.path,
         Assets.images.mainTabHomeSelected.path,
         "#969696".toColor(),
         "#969696".toColor(),
         ColorName.commonTxtColor),
         ColorName.commonTxtColor),
     TabBean(
     TabBean(
-        'main_tab_file'.tr,
+        StringName.mainTabFile,
         Assets.images.mainTabFileUnSelect.path,
         Assets.images.mainTabFileUnSelect.path,
         Assets.images.mainTabFileSelected.path,
         Assets.images.mainTabFileSelected.path,
         "#969696".toColor(),
         "#969696".toColor(),

+ 65 - 44
lib/module/main/view.dart

@@ -1,32 +1,32 @@
 import 'package:electronic_assistant/base/base_page.dart';
 import 'package:electronic_assistant/base/base_page.dart';
+import 'package:electronic_assistant/main.dart';
 import 'package:electronic_assistant/module/main/controller.dart';
 import 'package:electronic_assistant/module/main/controller.dart';
+import 'package:electronic_assistant/resource/assets.gen.dart';
+import 'package:electronic_assistant/resource/colors.gen.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
 import 'package:get/get.dart';
 
 
+import '../files/view.dart';
+import '../home/view.dart';
+
 class MainTabPage extends BasePage<MainController> {
 class MainTabPage extends BasePage<MainController> {
-  const MainTabPage({super.key});
+  MainTabPage({super.key});
+
+  final pages = [
+    const HomePage(),
+    const FilesPage(),
+  ];
 
 
   @override
   @override
   Widget? buildBody(BuildContext context) {
   Widget? buildBody(BuildContext context) {
     return Scaffold(
     return Scaffold(
-      body: const Center(
-        child: Text('MainTabPage'),
-      ),
-      bottomNavigationBar: BottomAppBar(
-        color: Colors.white,
-        height: 68,
-        shape: const CircularNotchedRectangle(),
-        child: Obx(() {
-          return Row(
-            mainAxisAlignment: MainAxisAlignment.spaceAround,
-            children: <Widget>[
-              SizedBox(child: bottomAppBarItem(0)),
-              const SizedBox(),
-              SizedBox(child: bottomAppBarItem(1)),
-            ],
-          );
-        }),
-      ),
+      body: Obx(() {
+        return pages[controller.currentIndex];
+      }),
+      floatingActionButton: buildAIChatBtn(),
+      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
+      bottomNavigationBar: buildBottomAppBar(),
       drawer: Drawer(
       drawer: Drawer(
         child: Center(
         child: Center(
           child: Column(
           child: Column(
@@ -44,6 +44,48 @@ class MainTabPage extends BasePage<MainController> {
     );
     );
   }
   }
 
 
+  Container buildAIChatBtn() {
+    return Container(
+      width: 68.w,
+      height: 68.w,
+      decoration: const BoxDecoration(
+        color: ColorName.white,
+        shape: BoxShape.circle,
+      ),
+      margin: EdgeInsets.only(top: 36.w),
+      padding: EdgeInsets.all(6.w),
+      child: Assets.images.mainTabSecretary.image(),
+    );
+  }
+
+  BottomAppBar buildBottomAppBar() {
+    return BottomAppBar(
+      color: Colors.white,
+      height: 68.h,
+      child: Obx(() {
+        return Flex(
+          mainAxisAlignment: MainAxisAlignment.spaceAround,
+          direction: Axis.horizontal,
+          children: <Widget>[
+            Expanded(
+              flex: 1,
+              child: bottomAppBarItem(0),
+            ),
+            const Expanded(
+              flex: 1,
+              child: SizedBox(),
+            ),
+            const SizedBox(),
+            Expanded(
+              flex: 1,
+              child: bottomAppBarItem(1),
+            ),
+          ],
+        );
+      }),
+    );
+  }
+
   Widget bottomAppBarItem(int index) {
   Widget bottomAppBarItem(int index) {
     //设置默认未选中的状态
     //设置默认未选中的状态
     TextStyle style;
     TextStyle style;
@@ -51,10 +93,10 @@ class MainTabPage extends BasePage<MainController> {
     String imagePath;
     String imagePath;
     if (controller.currentIndex == index) {
     if (controller.currentIndex == index) {
       //选中的话
       //选中的话
-      style = TextStyle(fontSize: 10, color: tabBean.txtSelectedColor);
+      style = TextStyle(fontSize: 10.sp, color: tabBean.txtSelectedColor);
       imagePath = tabBean.selectedIcon;
       imagePath = tabBean.selectedIcon;
     } else {
     } else {
-      style = TextStyle(fontSize: 10, color: tabBean.txtNormalColor);
+      style = TextStyle(fontSize: 10.sp, color: tabBean.txtNormalColor);
       imagePath = tabBean.normalIcon;
       imagePath = tabBean.normalIcon;
     }
     }
     //构造返回的Widget
     //构造返回的Widget
@@ -64,9 +106,9 @@ class MainTabPage extends BasePage<MainController> {
         child: Column(
         child: Column(
           mainAxisSize: MainAxisSize.min,
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
           children: <Widget>[
-            Image.asset(imagePath, width: 24, height: 24),
+            Image.asset(imagePath, width: 24.w, height: 24.w),
             Text(
             Text(
-              tabBean.title,
+              tabBean.title.tr,
               style: style,
               style: style,
             )
             )
           ],
           ],
@@ -80,25 +122,4 @@ class MainTabPage extends BasePage<MainController> {
     );
     );
     return item;
     return item;
   }
   }
-
-// List<BottomNavigationBarItem> get _buildBottomBarItem {
-//   return [
-//     BottomNavigationBarItem(
-//       icon: Assets.images.mainTabHomeUnSelect.image(width: 24, height: 24),
-//       activeIcon:
-//           Assets.images.mainTabHomeSelected.image(width: 24, height: 24),
-//       label: 'main_tab_home'.tr,
-//     ),
-//     const BottomNavigationBarItem(
-//       icon: SizedBox(width: 24, height: 24),
-//       label: '',
-//     ),
-//     BottomNavigationBarItem(
-//       icon: Assets.images.mainTabFileUnSelect.image(width: 24, height: 24),
-//       activeIcon:
-//           Assets.images.mainTabFileSelected.image(width: 24, height: 24),
-//       label: 'main_tab_file'.tr,
-//     ),
-//   ];
-// }
 }
 }

+ 2 - 7
lib/resource/string_source.dart

@@ -1,12 +1,7 @@
+import 'package:electronic_assistant/resource/string.gen.dart';
 import 'package:get/get.dart';
 import 'package:get/get.dart';
 
 
 class StringResource extends Translations {
 class StringResource extends Translations {
   @override
   @override
-  Map<String, Map<String, String>> get keys => {
-        'zh_CN': {
-          'app_name': '电子秘书',
-          'main_tab_home': '首页',
-          'main_tab_file': '文件',
-        }
-      };
+  Map<String, Map<String, String>> get keys => StringMultiSource.values;
 }
 }

+ 1 - 1
lib/router/app_pages.dart

@@ -36,6 +36,6 @@ class AppBinding extends Bindings {
 final generalPages = [
 final generalPages = [
   GetPage(name: RoutePath.splash, page: () => const SplashPage()),
   GetPage(name: RoutePath.splash, page: () => const SplashPage()),
   GetPage(name: RoutePath.login, page: () => const LoginPage()),
   GetPage(name: RoutePath.login, page: () => const LoginPage()),
-  GetPage(name: RoutePath.mainTab, page: () => const MainTabPage()),
+  GetPage(name: RoutePath.mainTab, page: () => MainTabPage()),
   GetPage(name: RoutePath.files, page: () => const FilesPage()),
   GetPage(name: RoutePath.files, page: () => const FilesPage()),
 ];
 ];

+ 99 - 0
string_resource_builder.dart

@@ -0,0 +1,99 @@
+import 'dart:async';
+import 'dart:io';
+import 'package:build/build.dart';
+import 'package:xml/xml.dart';
+
+const baseType = 'zh_CN';
+
+Builder builds(BuilderOptions options) => StringResourceBuilder();
+
+class StringResourceBuilder implements Builder {
+  @override
+  Future<void> build(BuildStep buildStep) async {
+    generateStringResources();
+  }
+
+  @override
+  Map<String, List<String>> get buildExtensions => {
+        '.xml': ['.s.dart'],
+      };
+}
+
+void main() {
+  generateStringResources();
+}
+
+void generateStringResources() {
+  print('generateStringResources...start');
+  final directory = Directory('assets/string/');
+
+  final buffer = StringBuffer();
+  final multiBuffer = StringBuffer();
+  buffer.writeln('class StringName {');
+  buffer.writeln('StringName._();');
+
+  multiBuffer.writeln('class StringMultiSource {');
+  multiBuffer.writeln('StringMultiSource._();');
+  multiBuffer
+      .writeln('  static const Map<String, Map<String, String>> values = {');
+  directory.listSync(recursive: true).forEach((element) {
+    if (element is Directory) {
+      final files =
+          element.listSync().where((file) => file.path.endsWith('.xml'));
+      bool isBase = element.path.endsWith('base');
+      String node = isBase ? baseType : element.path.split('/').last;
+      for (var file in files) {
+        final content = File(file.path).readAsStringSync();
+        final document = XmlDocument.parse(content);
+        final strings = document.findAllElements('string');
+        multiBuffer.writeln('    \'$node\': {');
+        for (var string in strings) {
+          final name = string.getAttribute('name');
+          final value = string.text;
+          if (isBase) {
+            final camelCaseName = toCamelCase(name);
+            buffer.writeln('  static const String $camelCaseName = \'$name\';');
+          }
+          multiBuffer.writeln('      \'$name\': \'$value\',');
+        }
+        multiBuffer.writeln('    },');
+      }
+    }
+  });
+
+  multiBuffer.writeln('  };');
+  multiBuffer.writeln('}');
+
+  buffer.writeln('}');
+  buffer.writeln();
+  buffer.writeln(multiBuffer.toString());
+
+  createDirectory('lib/resource');
+  final outputFile = File('lib/resource/string.gen.dart');
+  outputFile.writeAsStringSync(buffer.toString());
+
+  print('Strings file generated successfully!');
+}
+
+void createDirectory(String path) {
+  final directory = Directory(path);
+  if (!directory.existsSync()) {
+    directory.createSync(recursive: true);
+    print('Directory created: $path');
+  } else {
+    print('Directory already exists: $path');
+  }
+}
+
+String toCamelCase(String? snakeCase) {
+  if (snakeCase == null) {
+    return '';
+  }
+  return snakeCase.split('_').map((word) {
+    if (word == snakeCase.split('_').first) {
+      return word;
+    } else {
+      return word[0].toUpperCase() + word.substring(1);
+    }
+  }).join('');
+}