Prechádzať zdrojové kódy

[new]增加首页布局

zk 9 mesiacov pred
rodič
commit
0cde2f05bf
38 zmenil súbory, kde vykonal 833 pridanie a 29 odobranie
  1. 1 10
      assets/color/color.xml
  2. BIN
      assets/images/bg_add_friend_dialog.webp
  3. BIN
      assets/images/bg_splash.webp
  4. BIN
      assets/images/icon_login_address_book.webp
  5. BIN
      assets/images/icon_login_close.webp
  6. BIN
      assets/images/icon_login_go_wx_arrow.webp
  7. BIN
      assets/images/icon_login_phone.webp
  8. BIN
      assets/images/icon_login_wx.webp
  9. BIN
      assets/images/icon_logo.webp
  10. BIN
      assets/images/icon_main_add_friend.webp
  11. BIN
      assets/images/icon_main_friend_guard.webp
  12. BIN
      assets/images/icon_main_help.webp
  13. BIN
      assets/images/icon_main_map_clock.webp
  14. BIN
      assets/images/icon_main_mine.webp
  15. BIN
      assets/images/icon_main_news.webp
  16. BIN
      assets/images/icon_main_refresh_friend_location.webp
  17. BIN
      assets/images/icon_main_refresh_mine_location.webp
  18. BIN
      assets/images/icon_splash_title.webp
  19. 11 0
      assets/string/base/string.xml
  20. 30 0
      lib/base/get_it.config.dart
  21. 12 0
      lib/base/get_it.dart
  22. 7 0
      lib/data/consts/build_config.dart
  23. 4 0
      lib/data/repositories/account_repository.dart
  24. 39 0
      lib/di/network_module.dart
  25. 5 1
      lib/main.dart
  26. 3 0
      lib/module/friend/add_friend/add_friend_dialog_controller.dart
  27. 223 0
      lib/module/friend/add_friend/add_friend_view.dart
  28. 181 1
      lib/module/main/main_page.dart
  29. 4 1
      lib/module/splash/splash_controller.dart
  30. 32 1
      lib/module/splash/splash_page.dart
  31. 178 0
      lib/resource/assets.gen.dart
  32. 2 14
      lib/resource/colors.gen.dart
  33. 23 1
      lib/resource/string.gen.dart
  34. 2 0
      lib/router/app_pages.dart
  35. 27 0
      lib/utils/expand.dart
  36. 13 0
      lib/widget/map_view.dart
  37. 32 0
      pubspec.lock
  38. 4 0
      pubspec.yaml

+ 1 - 10
assets/color/color.xml

@@ -2,7 +2,7 @@
 <resources>
     <color name="transparent">#00FFFFFF</color>
     <!--主题色文字色彩-->
-    <color name="colorPrimary">#374BFF</color>
+    <color name="colorPrimary">#7B7DFF</color>
     <!--主题色点缀色-->
     <color name="colorAccentPrimary">#6399FF</color>
     <!--主题色背景色-->
@@ -14,15 +14,6 @@
     <color name="primaryTextColor">#E6000000</color>
     <!--次要文字色彩-->
     <color name="secondaryTextColor">#99000000</color>
-    <!--占位符文字色彩-->
-    <color name="placeholderTextColor">#66000000</color>
-    <!--文字disabled态-->
-    <color name="disabledTextColor">#42000000</color>
-    <!--文字反色色彩-->
-    <color name="inverseTextColor">#FFFFFFFF</color>
 
 
-    <!--导航栏未选中时文本颜色-->
-    <color name="TabUnSelectTextColor">#FFB8C1D6</color>
-
 </resources>

BIN
assets/images/bg_add_friend_dialog.webp


BIN
assets/images/bg_splash.webp


BIN
assets/images/icon_login_address_book.webp


BIN
assets/images/icon_login_close.webp


BIN
assets/images/icon_login_go_wx_arrow.webp


BIN
assets/images/icon_login_phone.webp


BIN
assets/images/icon_login_wx.webp


BIN
assets/images/icon_logo.webp


BIN
assets/images/icon_main_add_friend.webp


BIN
assets/images/icon_main_friend_guard.webp


BIN
assets/images/icon_main_help.webp


BIN
assets/images/icon_main_map_clock.webp


BIN
assets/images/icon_main_mine.webp


BIN
assets/images/icon_main_news.webp


BIN
assets/images/icon_main_refresh_friend_location.webp


BIN
assets/images/icon_main_refresh_mine_location.webp


BIN
assets/images/icon_splash_title.webp


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

@@ -13,5 +13,16 @@
     <string name="load_no_data">没有更多数据了</string>
     <string name="load_failed">加载失败</string>
 
+    <string name="friend_add_title">添加好友</string>
+    <string name="friend_add_desc">查看实时定位,开启轨迹守护</string>
+    <string name="friend_add_phone_et_hint">请输入手机号</string>
+    <string name="friend_add_address_book">通讯录</string>
+    <string name="friend_add_from_wx">通过微信添加</string>
+    <string name="friend_add_rule">定位功能需要双方同意方可使用</string>
+
+    <string name="main_friend_list_tab">好友守护</string>
+    <string name="main_news_tab">消息中心</string>
+    <string name="main_help_tab">一键求助</string>
+    <string name="main_mine_tab">个人中心</string>
 
 </resources>

+ 30 - 0
lib/base/get_it.config.dart

@@ -0,0 +1,30 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// **************************************************************************
+// InjectableConfigGenerator
+// **************************************************************************
+
+// ignore_for_file: type=lint
+// coverage:ignore-file
+
+// ignore_for_file: no_leading_underscores_for_library_prefixes
+import 'package:get_it/get_it.dart' as _i174;
+import 'package:injectable/injectable.dart' as _i526;
+
+import '../data/repositories/account_repository.dart' as _i20;
+
+extension GetItInjectableX on _i174.GetIt {
+// initializes the registration of main-scope dependencies inside of GetIt
+  _i174.GetIt init({
+    String? environment,
+    _i526.EnvironmentFilter? environmentFilter,
+  }) {
+    final gh = _i526.GetItHelper(
+      this,
+      environment,
+      environmentFilter,
+    );
+    gh.lazySingleton<_i20.AccountRepository>(() => _i20.AccountRepository());
+    return this;
+  }
+}

+ 12 - 0
lib/base/get_it.dart

@@ -0,0 +1,12 @@
+import 'package:injectable/injectable.dart';
+import 'package:get_it/get_it.dart';
+import 'package:location/base/get_it.config.dart';
+
+final getIt = GetIt.instance;
+
+@InjectableInit(
+  initializerName: 'init', // default
+  preferRelativeImports: true, // default
+  asExtension: true, // default
+)
+void configureDependencies() => getIt.init();

+ 7 - 0
lib/data/consts/build_config.dart

@@ -0,0 +1,7 @@
+import 'package:flutter/foundation.dart';
+
+final class BuildConfig {
+  BuildConfig._();
+
+  static bool get isDebug => kDebugMode;
+}

+ 4 - 0
lib/data/repositories/account_repository.dart

@@ -0,0 +1,4 @@
+import 'package:injectable/injectable.dart';
+
+@lazySingleton
+class AccountRepository {}

+ 39 - 0
lib/di/network_module.dart

@@ -0,0 +1,39 @@
+import 'package:dio/dio.dart';
+import 'package:pretty_dio_logger/pretty_dio_logger.dart';
+
+import '../data/consts/build_config.dart';
+
+class _NetworkModule {
+  static Dio _createDefaultDio() {
+    Dio dio = Dio(BaseOptions());
+    dio.interceptors.add(PrettyDioLogger(
+      requestHeader: true,
+      requestBody: true,
+      responseBody: true,
+      responseHeader: false,
+      error: true,
+      compact: true,
+      enabled: BuildConfig.isDebug,
+    ));
+    return dio;
+  }
+
+  static Dio _createFileDio() {
+    Dio dio = Dio(BaseOptions(
+      sendTimeout: const Duration(seconds: 15),
+      receiveTimeout: const Duration(seconds: 15),
+    ));
+    dio.interceptors.add(PrettyDioLogger(
+      requestHeader: true,
+      requestBody: true,
+      responseBody: true,
+      responseHeader: true,
+      enabled: BuildConfig.isDebug,
+    ));
+    return dio;
+  }
+}
+
+final defaultDio = _NetworkModule._createDefaultDio();
+
+final fileDio = _NetworkModule._createFileDio();

+ 5 - 1
lib/main.dart

@@ -9,9 +9,13 @@ import 'package:location/resource/string_source.dart';
 import 'package:location/router/app_pages.dart';
 import 'package:pull_to_refresh/pull_to_refresh.dart';
 
+import 'base/get_it.dart';
+
 void main() async {
   WidgetsFlutterBinding.ensureInitialized();
 
+  configureDependencies();
+
   runApp(const MyApp());
 }
 
@@ -21,7 +25,7 @@ class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return ScreenUtilInit(
-      designSize: const Size(360, 800),
+      designSize: const Size(360, 640),
       builder: (_, child) {
         return _buildMaterialApp();
       },

+ 3 - 0
lib/module/friend/add_friend/add_friend_dialog_controller.dart

@@ -0,0 +1,3 @@
+import '../../../base/base_controller.dart';
+
+class AddFriendDialogController extends BaseController {}

+ 223 - 0
lib/module/friend/add_friend/add_friend_view.dart

@@ -0,0 +1,223 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:get/get_core/src/get_main.dart';
+import 'package:location/utils/expand.dart';
+import '../../../base/base_view.dart';
+import '../../../resource/assets.gen.dart';
+import '../../../resource/colors.gen.dart';
+import '../../../resource/string.gen.dart';
+import 'add_friend_dialog_controller.dart';
+
+class AddFriendView extends BaseView<AddFriendDialogController> {
+  const AddFriendView({super.key});
+
+  static void show() {
+    Get.bottomSheet(AddFriendView(),
+        isScrollControlled: true,
+        barrierColor: ColorName.black55,
+        backgroundColor: ColorName.transparent);
+  }
+
+  static void dismiss() {
+    Get.back();
+  }
+
+  @override
+  Widget buildBody(BuildContext context) {
+    return _addFriendView();
+  }
+
+  @override
+  backgroundColor() {
+    return ColorName.transparent;
+  }
+
+  Widget _addFriendView() {
+    return IntrinsicHeight(
+      child: Container(
+        decoration: BoxDecoration(
+          color: '#FDFCFE'.color,
+          borderRadius: BorderRadius.only(
+            topLeft: Radius.circular(16.w),
+            topRight: Radius.circular(16.w),
+          ),
+        ),
+        child: Stack(
+          children: [
+            // Positioned.fill(
+            //   child: Assets.images.bgAddFriendDialog.image(width: 1.sw),
+            // ),
+            _buildClose(),
+            Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SizedBox(height: 19.h),
+                _buildAddHeader(),
+                SizedBox(height: 18.h),
+                _buildPhone(),
+                SizedBox(height: 16.h),
+                _buildShareWx(),
+                SizedBox(height: 20.h),
+                Center(
+                    child: Text(StringName.friendAddRule,
+                        style: TextStyle(
+                            fontSize: 12.sp, color: '#A7A7A7'.color))),
+                SizedBox(height: 30.h),
+              ],
+            )
+          ],
+        ),
+      ),
+    );
+  }
+
+  Container _buildShareWx() {
+    return Container(
+      height: 54.w,
+      decoration: BoxDecoration(boxShadow: [
+        BoxShadow(
+          color: ColorName.black5.withOpacity(0.05), // 阴影颜色
+          blurRadius: 23, // 阴影模糊半径
+          spreadRadius: 2, // 阴影扩展半径
+          offset: const Offset(0, 0), // 阴影位置,向上偏移
+        ),
+      ], color: ColorName.white, borderRadius: BorderRadius.circular(12.w)),
+      margin: EdgeInsets.symmetric(horizontal: 12.w),
+      child: Row(
+        children: [
+          SizedBox(width: 15.w),
+          Assets.images.iconLoginWx.image(width: 25.w),
+          SizedBox(width: 15.w),
+          Text(StringName.friendAddFromWx,
+              style: TextStyle(
+                  fontWeight: FontWeight.bold,
+                  color: ColorName.primaryTextColor,
+                  fontSize: 14.sp)),
+          Spacer(),
+          Assets.images.iconLoginGoWxArrow.image(width: 18.w, height: 18.w),
+          SizedBox(width: 12.w),
+        ],
+      ),
+    );
+  }
+
+  Container _buildPhone() {
+    return Container(
+      padding: EdgeInsets.symmetric(horizontal: 12.w),
+      margin: EdgeInsets.symmetric(horizontal: 12.w),
+      decoration: BoxDecoration(boxShadow: [
+        BoxShadow(
+          color: ColorName.black5.withOpacity(0.05), // 阴影颜色
+          blurRadius: 23, // 阴影模糊半径
+          spreadRadius: 2, // 阴影扩展半径
+          offset: const Offset(0, 0), // 阴影位置,向上偏移
+        ),
+      ], color: ColorName.white, borderRadius: BorderRadius.circular(12.w)),
+      child: Column(
+        children: [
+          SizedBox(height: 13.h),
+          Row(
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              Assets.images.iconLoginPhone.image(width: 18.w, height: 18.w),
+              SizedBox(width: 7.w),
+              Text(
+                StringName.friendAddPhoneEtHint,
+                style: TextStyle(
+                  fontWeight: FontWeight.bold,
+                  fontSize: 14.sp,
+                  color: ColorName.primaryTextColor,
+                ),
+              )
+            ],
+          ),
+          SizedBox(height: 18.h),
+          _buildPhoneView(),
+          SizedBox(height: 18.h),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildPhoneView() {
+    return Row(
+      children: [
+        Expanded(
+          child: Container(
+            height: 50.w,
+            decoration: BoxDecoration(
+              color: '#F9F9F9'.color,
+              borderRadius: BorderRadius.circular(10.w),
+            ),
+            padding: EdgeInsets.symmetric(horizontal: 10.w),
+            child: Center(
+              child: TextField(
+                style: TextStyle(
+                    fontSize: 14.sp, color: ColorName.primaryTextColor),
+                maxLines: 1,
+                maxLength: 11,
+                keyboardType: TextInputType.phone,
+                textAlignVertical: TextAlignVertical.center,
+                textInputAction: TextInputAction.next,
+                decoration: InputDecoration(
+                  hintText: StringName.friendAddPhoneEtHint,
+                  counterText: '',
+                  hintStyle:
+                      TextStyle(fontSize: 16, color: "#AFAFAF".toColor()),
+                  labelStyle: const TextStyle(
+                    fontSize: 16,
+                    color: ColorName.primaryTextColor,
+                  ),
+                  contentPadding: const EdgeInsets.all(0),
+                  border: const OutlineInputBorder(borderSide: BorderSide.none),
+                  enabled: true,
+                ),
+              ),
+            ),
+          ),
+        ),
+        SizedBox(width: 14.w),
+        Assets.images.iconLoginAddressBook.image(width: 15.w, height: 15.w),
+        SizedBox(width: 3.w),
+        Text(StringName.friendAddAddressBook,
+            style: TextStyle(fontSize: 14.sp, color: '#202020'.color)),
+      ],
+    );
+  }
+
+  Widget _buildAddHeader() {
+    return Padding(
+      padding: EdgeInsets.only(left: 18.w),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Text(StringName.friendAddTitle,
+              style: TextStyle(
+                  fontSize: 20.sp,
+                  color: ColorName.primaryTextColor,
+                  fontWeight: FontWeight.bold)),
+          SizedBox(height: 10.h),
+          Text(StringName.friendAddDesc,
+              style: TextStyle(fontSize: 14.sp, color: '#545454'.color)),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildClose() {
+    return Padding(
+      padding: EdgeInsets.all(12.w),
+      child: GestureDetector(
+        onTap: () {
+          Get.back();
+        },
+        child: Align(
+            alignment: Alignment.topRight,
+            child:
+                Assets.images.iconLoginClose.image(width: 24.w, height: 24.w)),
+      ),
+    );
+  }
+}

+ 181 - 1
lib/module/main/main_page.dart

@@ -1,13 +1,193 @@
 import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:get/get_core/src/get_main.dart';
 import 'package:location/base/base_page.dart';
 import 'package:location/module/main/main_controller.dart';
+import 'package:location/resource/assets.gen.dart';
+import 'package:location/resource/colors.gen.dart';
+import 'package:location/resource/string.gen.dart';
+import 'package:location/utils/expand.dart';
+import 'package:location/widget/map_view.dart';
+import '../../router/app_pages.dart';
 
 class MainPage extends BasePage<MainController> {
   const MainPage({super.key});
 
+  static start({bool? isNotClear}) {
+    if (isNotClear == null || !isNotClear) {
+      Get.offAllNamed(RoutePath.mainTab);
+    } else {
+      Get.toNamed(RoutePath.mainTab);
+    }
+  }
+
+  @override
+  bool immersive() {
+    return true;
+  }
+
   @override
   Widget buildBody(BuildContext context) {
-    return Text('123');
+    return Stack(
+      children: [
+        Padding(
+          padding: EdgeInsets.only(bottom: 50.h),
+          child: SizedBox(width: double.infinity, child: MapView()),
+        ),
+        Align(
+          alignment: Alignment.bottomCenter,
+          child: IntrinsicHeight(
+            child: Column(
+              children: [
+                Row(
+                  crossAxisAlignment: CrossAxisAlignment.end,
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Container(
+                        margin: EdgeInsets.only(bottom: 24.w, left: 12.w),
+                        child:
+                            Assets.images.iconMainMapClock.image(width: 50.w)),
+                    Align(
+                      alignment: Alignment.bottomRight,
+                      child: Column(
+                        children: [
+                          Container(
+                              margin: EdgeInsets.only(right: 12.w),
+                              child: Assets.images.iconMainRefreshFriendLocation
+                                  .image(width: 42.w, height: 42.w)),
+                          SizedBox(height: 14.w),
+                          Container(
+                              margin: EdgeInsets.only(right: 12.w),
+                              child: Assets.images.iconMainRefreshMineLocation
+                                  .image(width: 42.w, height: 42.w)),
+                          SizedBox(height: 20.w)
+                        ],
+                      ),
+                    )
+                  ],
+                ),
+                Container(
+                  decoration: BoxDecoration(
+                    color: '#F9F9F9'.color,
+                    borderRadius: BorderRadius.only(
+                      topLeft: Radius.circular(20.w),
+                      topRight: Radius.circular(20.w),
+                    ),
+                  ),
+                  child: Column(
+                    children: [
+                      SizedBox(height: 5.w),
+                      Container(
+                        width: 32.w,
+                        height: 3.w,
+                        decoration: BoxDecoration(
+                            color: '#D9D9D9'.color,
+                            borderRadius:
+                                BorderRadius.all(Radius.circular(49.w))),
+                      ),
+                      SizedBox(height: 12.w),
+                      buildSelectFriendInfoView(),
+                      SizedBox(height: 13.w),
+                      buildTabContainer()
+                    ],
+                  ),
+                )
+              ],
+            ),
+          ),
+        ),
+        SafeArea(
+          child: Container(
+            margin: EdgeInsets.only(top: 26.w),
+            child: Row(
+              children: [
+                Expanded(child: Text('好友列表')),
+                Container(
+                    margin: EdgeInsets.only(right: 16.w, left: 8.w),
+                    child: Assets.images.iconMainAddFriend
+                        .image(width: 60.w, height: 60.w))
+              ],
+            ),
+          ),
+        )
+      ],
+    );
+  }
+
+  Container buildTabContainer() {
+    return Container(
+        decoration: BoxDecoration(
+          color: ColorName.white,
+          borderRadius: BorderRadius.only(
+            topLeft: Radius.circular(20.w),
+            topRight: Radius.circular(20.w),
+          ),
+        ),
+        padding: EdgeInsets.only(top: 13.w, bottom: 23.w),
+        child: buildMainFunList());
+  }
+
+  Widget buildMainFunList() {
+    return Row(
+      children: [
+        Expanded(
+            child: buildFunItem(Assets.images.iconMainFriendGuard.provider(),
+                StringName.mainFriendListTab, () {})),
+        Expanded(
+            child: buildFunItem(Assets.images.iconMainNews.provider(),
+                StringName.mainNewsTab, () {},
+                isShowDot: true)),
+        Expanded(
+            child: buildFunItem(Assets.images.iconMainHelp.provider(),
+                StringName.mainHelpTab, () {})),
+        Expanded(
+            child: buildFunItem(Assets.images.iconMainMine.provider(),
+                StringName.mainMineTab, () {}))
+      ],
+    );
+  }
+
+  Widget buildFunItem(ImageProvider imgProvider, String title, Function() onTap,
+      {bool? isShowDot}) {
+    return Column(
+      children: [
+        Stack(children: [
+          SizedBox(width: 44.w, height: 44.w, child: Image(image: imgProvider)),
+          Visibility(
+            visible: isShowDot ?? false,
+            child: Positioned(
+              top: 6.w,
+              right: 6.w,
+              child: Container(
+                width: 10.w,
+                height: 10.w,
+                decoration: BoxDecoration(
+                  shape: BoxShape.circle,
+                  color: '#FF333D'.color, // 背景颜色
+                ),
+              ),
+            ),
+          )
+        ]),
+        Text(title,
+            style: TextStyle(
+                fontSize: 12.sp,
+                color: ColorName.black70,
+                fontWeight: FontWeight.bold))
+      ],
+    );
+  }
+
+  Widget buildSelectFriendInfoView() {
+    return Container(
+        decoration: BoxDecoration(
+            color: ColorName.white,
+            borderRadius: BorderRadius.all(Radius.circular(20.w))),
+        child: Row(
+          children: [],
+        ));
   }
 }

+ 4 - 1
lib/module/splash/splash_controller.dart

@@ -1,3 +1,6 @@
 import 'package:location/base/base_controller.dart';
 
-class SplashController extends BaseController {}
+class SplashController extends BaseController {
+  @override
+  void onReady() {}
+}

+ 32 - 1
lib/module/splash/splash_page.dart

@@ -1,13 +1,44 @@
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:location/base/base_page.dart';
 import 'package:location/module/splash/splash_controller.dart';
+import 'package:location/resource/assets.gen.dart';
+
+import '../main/main_page.dart';
 
 class SplashPage extends BasePage<SplashController> {
   const SplashPage({super.key});
 
   @override
+  bool immersive() {
+    return true;
+  }
+
+  @override
   Widget buildBody(BuildContext context) {
-    return Text('123');
+    Future.delayed(Duration(seconds: 1), () {
+      MainPage.start();
+    });
+    //测试代码
+
+    return Stack(
+      children: [
+        Assets.images.bgSplash.image(width: double.infinity),
+        Column(
+          children: [
+            SizedBox(height: 170.h),
+            Center(
+                child: Assets.images.iconLogo.image(width: 76.w, height: 76.w)),
+          ],
+        ),
+        Padding(
+          padding: EdgeInsets.only(bottom: 40.h),
+          child: Align(
+              alignment: Alignment.bottomCenter,
+              child: Assets.images.iconSplashTitle.image(width: 167.w)),
+        )
+      ],
+    );
   }
 }

+ 178 - 0
lib/resource/assets.gen.dart

@@ -7,6 +7,184 @@
 // ignore_for_file: type=lint
 // ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use
 
+import 'package:flutter/widgets.dart';
+
+class $AssetsImagesGen {
+  const $AssetsImagesGen();
+
+  /// File path: assets/images/bg_add_friend_dialog.webp
+  AssetGenImage get bgAddFriendDialog =>
+      const AssetGenImage('assets/images/bg_add_friend_dialog.webp');
+
+  /// File path: assets/images/bg_splash.webp
+  AssetGenImage get bgSplash =>
+      const AssetGenImage('assets/images/bg_splash.webp');
+
+  /// File path: assets/images/icon_login_address_book.webp
+  AssetGenImage get iconLoginAddressBook =>
+      const AssetGenImage('assets/images/icon_login_address_book.webp');
+
+  /// File path: assets/images/icon_login_close.webp
+  AssetGenImage get iconLoginClose =>
+      const AssetGenImage('assets/images/icon_login_close.webp');
+
+  /// File path: assets/images/icon_login_go_wx_arrow.webp
+  AssetGenImage get iconLoginGoWxArrow =>
+      const AssetGenImage('assets/images/icon_login_go_wx_arrow.webp');
+
+  /// File path: assets/images/icon_login_phone.webp
+  AssetGenImage get iconLoginPhone =>
+      const AssetGenImage('assets/images/icon_login_phone.webp');
+
+  /// File path: assets/images/icon_login_wx.webp
+  AssetGenImage get iconLoginWx =>
+      const AssetGenImage('assets/images/icon_login_wx.webp');
+
+  /// File path: assets/images/icon_logo.webp
+  AssetGenImage get iconLogo =>
+      const AssetGenImage('assets/images/icon_logo.webp');
+
+  /// File path: assets/images/icon_main_add_friend.webp
+  AssetGenImage get iconMainAddFriend =>
+      const AssetGenImage('assets/images/icon_main_add_friend.webp');
+
+  /// File path: assets/images/icon_main_friend_guard.webp
+  AssetGenImage get iconMainFriendGuard =>
+      const AssetGenImage('assets/images/icon_main_friend_guard.webp');
+
+  /// File path: assets/images/icon_main_help.webp
+  AssetGenImage get iconMainHelp =>
+      const AssetGenImage('assets/images/icon_main_help.webp');
+
+  /// File path: assets/images/icon_main_map_clock.webp
+  AssetGenImage get iconMainMapClock =>
+      const AssetGenImage('assets/images/icon_main_map_clock.webp');
+
+  /// File path: assets/images/icon_main_mine.webp
+  AssetGenImage get iconMainMine =>
+      const AssetGenImage('assets/images/icon_main_mine.webp');
+
+  /// File path: assets/images/icon_main_news.webp
+  AssetGenImage get iconMainNews =>
+      const AssetGenImage('assets/images/icon_main_news.webp');
+
+  /// File path: assets/images/icon_main_refresh_friend_location.webp
+  AssetGenImage get iconMainRefreshFriendLocation => const AssetGenImage(
+      'assets/images/icon_main_refresh_friend_location.webp');
+
+  /// File path: assets/images/icon_main_refresh_mine_location.webp
+  AssetGenImage get iconMainRefreshMineLocation =>
+      const AssetGenImage('assets/images/icon_main_refresh_mine_location.webp');
+
+  /// File path: assets/images/icon_splash_title.webp
+  AssetGenImage get iconSplashTitle =>
+      const AssetGenImage('assets/images/icon_splash_title.webp');
+
+  /// List of all assets
+  List<AssetGenImage> get values => [
+        bgAddFriendDialog,
+        bgSplash,
+        iconLoginAddressBook,
+        iconLoginClose,
+        iconLoginGoWxArrow,
+        iconLoginPhone,
+        iconLoginWx,
+        iconLogo,
+        iconMainAddFriend,
+        iconMainFriendGuard,
+        iconMainHelp,
+        iconMainMapClock,
+        iconMainMine,
+        iconMainNews,
+        iconMainRefreshFriendLocation,
+        iconMainRefreshMineLocation,
+        iconSplashTitle
+      ];
+}
+
 class Assets {
   const Assets._();
+
+  static const $AssetsImagesGen images = $AssetsImagesGen();
+}
+
+class AssetGenImage {
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
+
+  final String _assetName;
+
+  final Size? size;
+  final Set<String> flavors;
+
+  Image image({
+    Key? key,
+    AssetBundle? bundle,
+    ImageFrameBuilder? frameBuilder,
+    ImageErrorWidgetBuilder? errorBuilder,
+    String? semanticLabel,
+    bool excludeFromSemantics = false,
+    double? scale,
+    double? width,
+    double? height,
+    Color? color,
+    Animation<double>? opacity,
+    BlendMode? colorBlendMode,
+    BoxFit? fit,
+    AlignmentGeometry alignment = Alignment.center,
+    ImageRepeat repeat = ImageRepeat.noRepeat,
+    Rect? centerSlice,
+    bool matchTextDirection = false,
+    bool gaplessPlayback = true,
+    bool isAntiAlias = false,
+    String? package,
+    FilterQuality filterQuality = FilterQuality.medium,
+    int? cacheWidth,
+    int? cacheHeight,
+  }) {
+    return Image.asset(
+      _assetName,
+      key: key,
+      bundle: bundle,
+      frameBuilder: frameBuilder,
+      errorBuilder: errorBuilder,
+      semanticLabel: semanticLabel,
+      excludeFromSemantics: excludeFromSemantics,
+      scale: scale,
+      width: width,
+      height: height,
+      color: color,
+      opacity: opacity,
+      colorBlendMode: colorBlendMode,
+      fit: fit,
+      alignment: alignment,
+      repeat: repeat,
+      centerSlice: centerSlice,
+      matchTextDirection: matchTextDirection,
+      gaplessPlayback: gaplessPlayback,
+      isAntiAlias: isAntiAlias,
+      package: package,
+      filterQuality: filterQuality,
+      cacheWidth: cacheWidth,
+      cacheHeight: cacheHeight,
+    );
+  }
+
+  ImageProvider provider({
+    AssetBundle? bundle,
+    String? package,
+  }) {
+    return AssetImage(
+      _assetName,
+      bundle: bundle,
+      package: package,
+    );
+  }
+
+  String get path => _assetName;
+
+  String get keyName => _assetName;
 }

+ 2 - 14
lib/resource/colors.gen.dart

@@ -13,9 +13,6 @@ import 'package:flutter/material.dart';
 class ColorName {
   ColorName._();
 
-  /// Color: #FFB8C1D6
-  static const Color tabUnSelectTextColor = Color(0xFFB8C1D6);
-
   /// Color: #F5F6F8
   static const Color bgColorPrimary = Color(0xFFF5F6F8);
 
@@ -82,21 +79,12 @@ class ColorName {
   /// Color: #6399FF
   static const Color colorAccentPrimary = Color(0xFF6399FF);
 
-  /// Color: #374BFF
-  static const Color colorPrimary = Color(0xFF374BFF);
+  /// Color: #7B7DFF
+  static const Color colorPrimary = Color(0xFF7B7DFF);
 
   /// Color: #F6FAFF
   static const Color colorPrimaryLight = Color(0xFFF6FAFF);
 
-  /// Color: #42000000
-  static const Color disabledTextColor = Color(0x42000000);
-
-  /// Color: #FFFFFFFF
-  static const Color inverseTextColor = Color(0xFFFFFFFF);
-
-  /// Color: #66000000
-  static const Color placeholderTextColor = Color(0x66000000);
-
   /// Color: #E6000000
   static const Color primaryTextColor = Color(0xE6000000);
 

+ 23 - 1
lib/resource/string.gen.dart

@@ -12,11 +12,22 @@ class StringName {
   static final String loadingTxt = 'loading_txt'.tr; // 正在加载
   static final String loadNoData = 'load_no_data'.tr; // 没有更多数据了
   static final String loadFailed = 'load_failed'.tr; // 加载失败
+  static final String friendAddTitle = 'friend_add_title'.tr; // 添加好友
+  static final String friendAddDesc = 'friend_add_desc'.tr; // 查看实时定位,开启轨迹守护
+  static final String friendAddPhoneEtHint =
+      'friend_add_phone_et_hint'.tr; // 请输入手机号
+  static final String friendAddAddressBook =
+      'friend_add_address_book'.tr; // 通讯录
+  static final String friendAddFromWx = 'friend_add_from_wx'.tr; // 通过微信添加
+  static final String friendAddRule = 'friend_add_rule'.tr; // 定位功能需要双方同意方可使用
+  static final String mainFriendListTab = 'main_friend_list_tab'.tr; // 好友守护
+  static final String mainNewsTab = 'main_news_tab'.tr; // 消息中心
+  static final String mainHelpTab = 'main_help_tab'.tr; // 一键求助
+  static final String mainMineTab = 'main_mine_tab'.tr; // 个人中心
 }
 
 class StringMultiSource {
   StringMultiSource._();
-
   static const Map<String, Map<String, String>> values = {
     'zh_CN': {
       'app_name': '手机定位追迹',
@@ -28,6 +39,17 @@ class StringMultiSource {
       'loading_txt': '正在加载',
       'load_no_data': '没有更多数据了',
       'load_failed': '加载失败',
+      'friend_add_title': '添加好友',
+      'friend_add_desc': '查看实时定位,开启轨迹守护',
+      'friend_add_phone_et_hint': '请输入手机号',
+      'friend_add_address_book': '通讯录',
+      'friend_add_from_wx': '通过微信添加',
+      'friend_add_rule': '定位功能需要双方同意方可使用',
+      'main_friend_list_tab': '好友守护',
+      'main_news_tab': '消息中心',
+      'main_help_tab': '一键求助',
+      'main_mine_tab': '个人中心',
     },
   };
 }
+

+ 2 - 0
lib/router/app_pages.dart

@@ -1,4 +1,5 @@
 import 'package:get/get.dart';
+import 'package:location/module/friend/add_friend/add_friend_dialog_controller.dart';
 import 'package:location/module/main/main_page.dart';
 import '../module/main/main_controller.dart';
 import '../module/splash/splash_controller.dart';
@@ -19,6 +20,7 @@ class AppBinding extends Bindings {
   void dependencies() {
     lazyPut(() => SplashController());
     lazyPut(() => MainController());
+    lazyPut(() => AddFriendDialogController());
   }
 
   void lazyPut<S>(InstanceBuilderCallback<S> builder) {

+ 27 - 0
lib/utils/expand.dart

@@ -0,0 +1,27 @@
+import 'dart:ui';
+
+extension HexColor on String {
+  Color get color => toColor();
+
+  Color toColor() {
+    String hex = replaceAll('#', '');
+    if (hex.length == 6) {
+      hex = 'FF$hex';
+    }
+    return Color(int.parse(hex, radix: 16));
+  }
+}
+
+extension DoubleExtension on double {
+  String toFormattedString(int fractionDigits) {
+    if (this == toInt()) {
+      return toInt().toString();
+    } else {
+      return toStringAsFixed(fractionDigits);
+    }
+  }
+
+  double toFormattedDouble(int fractionDigits) {
+    return double.parse(toStringAsFixed(fractionDigits));
+  }
+}

+ 13 - 0
lib/widget/map_view.dart

@@ -0,0 +1,13 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:location/utils/expand.dart';
+
+class MapView extends StatelessWidget {
+  const MapView({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+        color: "#DAF2E2".color, child: Center(child: Text('这是地图页面,暂时没有开发')));
+  }
+}

+ 32 - 0
pubspec.lock

@@ -362,6 +362,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "4.7.2"
+  get_it:
+    dependency: transitive
+    description:
+      name: get_it
+      sha256: f126a3e286b7f5b578bf436d5592968706c4c1de28a228b870ce375d9f743103
+      url: "https://pub.dev"
+    source: hosted
+    version: "8.0.3"
   glob:
     dependency: transitive
     description:
@@ -418,6 +426,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.4.0"
+  injectable:
+    dependency: "direct main"
+    description:
+      name: injectable
+      sha256: "5e1556ea1d374fe44cbe846414d9bab346285d3d8a1da5877c01ad0774006068"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.5.0"
+  injectable_generator:
+    dependency: "direct dev"
+    description:
+      name: injectable_generator
+      sha256: af403d76c7b18b4217335e0075e950cd0579fd7f8d7bd47ee7c85ada31680ba1
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.6.2"
   intl:
     dependency: transitive
     description:
@@ -786,6 +810,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.0.0"
+  recase:
+    dependency: transitive
+    description:
+      name: recase
+      sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.1.0"
   retrofit:
     dependency: "direct main"
     description:

+ 4 - 0
pubspec.yaml

@@ -66,6 +66,9 @@ dependencies:
   flutter_localizations:
     sdk: flutter
 
+  #依赖注入
+  injectable: 2.5.0
+
   #日志打印
   atmob_logging:
     version: ^0.0.5
@@ -93,6 +96,7 @@ dev_dependencies:
 
   flutter_lints: ^5.0.0
 
+  injectable_generator: 2.6.2
 
 #----------gen配置---------------
 flutter_gen: