Browse Source

[new]优化首页界面内容显示

zk 2 months ago
parent
commit
aaf541e27e
35 changed files with 547 additions and 547 deletions
  1. BIN
      assets/images/bg_main_friend_card.webp
  2. BIN
      assets/images/bg_member_activity_main.webp
  3. BIN
      assets/images/icon_current_location.webp
  4. BIN
      assets/images/icon_main_add_friend.webp
  5. BIN
      assets/images/icon_main_friend.webp
  6. BIN
      assets/images/icon_main_friend_guard.webp
  7. BIN
      assets/images/icon_main_friend_guard_android.webp
  8. BIN
      assets/images/icon_main_help.webp
  9. BIN
      assets/images/icon_main_help_android.webp
  10. BIN
      assets/images/icon_main_left_slip_arrow.webp
  11. BIN
      assets/images/icon_main_location.webp
  12. BIN
      assets/images/icon_main_map_clock.webp
  13. BIN
      assets/images/icon_main_mine.webp
  14. BIN
      assets/images/icon_main_mine_android.webp
  15. BIN
      assets/images/icon_main_news.webp
  16. BIN
      assets/images/icon_main_news_android.webp
  17. BIN
      assets/images/icon_main_refresh.webp
  18. BIN
      assets/images/icon_main_track_location.webp
  19. BIN
      assets/images/icon_member_activity_coupon.webp
  20. BIN
      assets/images/img_main_caring_report.webp
  21. 3 0
      assets/string/base/string.xml
  22. 2 3
      lib/module/commonpoint/select_address/common_point_select_address_page.dart
  23. 39 0
      lib/module/main/main_common_view.dart
  24. 29 10
      lib/module/main/main_controller.dart
  25. 151 3
      lib/module/main/main_friend_item.dart
  26. 226 318
      lib/module/main/main_page.dart
  27. 0 1
      lib/module/member/activity/member_activity_page.dart
  28. 2 2
      lib/module/member/member_page.dart
  29. 31 46
      lib/resource/assets.gen.dart
  30. 7 0
      lib/resource/string.gen.dart
  31. 10 6
      lib/widget/activity_countdown_txt_view.dart
  32. 0 110
      lib/widget/activity_countdown_view.dart
  33. 36 45
      lib/widget/marquee_text.dart
  34. 1 1
      plugins/map/lib/src/core/map_base_controller.dart
  35. 10 2
      plugins/map/lib/src/entity/marker.dart

BIN
assets/images/bg_main_friend_card.webp


BIN
assets/images/bg_member_activity_main.webp


BIN
assets/images/icon_current_location.webp


BIN
assets/images/icon_main_add_friend.webp


BIN
assets/images/icon_main_friend.webp


BIN
assets/images/icon_main_friend_guard.webp


BIN
assets/images/icon_main_friend_guard_android.webp


BIN
assets/images/icon_main_help.webp


BIN
assets/images/icon_main_help_android.webp


BIN
assets/images/icon_main_left_slip_arrow.webp


BIN
assets/images/icon_main_location.webp


BIN
assets/images/icon_main_map_clock.webp


BIN
assets/images/icon_main_mine.webp


BIN
assets/images/icon_main_mine_android.webp


BIN
assets/images/icon_main_news.webp


BIN
assets/images/icon_main_news_android.webp


BIN
assets/images/icon_main_refresh.webp


BIN
assets/images/icon_main_track_location.webp


BIN
assets/images/icon_member_activity_coupon.webp


BIN
assets/images/img_main_caring_report.webp


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

@@ -3,6 +3,8 @@
     <string name="app_name">手机实时定位</string>
     <string name="app_name_ios">手机实时定位</string>
     <string name="main_tab_home">首页</string>
+    <string name="main_tab_friend">好友</string>
+    <string name="main_tab_news">消息</string>
     <string name="main_tab_camera">扫一扫</string>
     <string name="main_tab_mine">我的</string>
 
@@ -449,4 +451,5 @@
     <string name="current_location">[当前位置]</string>
     <string name="select_address_please">请在列表下方选择一个详细地址</string>
     <string name="dialog_add_friend_next_time">下次再说</string>
+    <string name="main_left_slip_switch">左\n滑\n切\n换</string>
 </resources>

+ 2 - 3
lib/module/commonpoint/select_address/common_point_select_address_page.dart

@@ -15,7 +15,6 @@ import 'package:location/utils/common_expand.dart';
 import 'package:pull_to_refresh/pull_to_refresh.dart';
 import 'package:sliding_sheet2/sliding_sheet2.dart';
 import '../../../router/app_pages.dart';
-import '../../../utils/common_util.dart';
 import '../../../widget/common_view.dart';
 import 'common_point_select_address_controller.dart';
 
@@ -80,8 +79,8 @@ class CommonPointSelectAddressPage
                   ],
                 ),
                 child: Center(
-                  child: Assets.images.iconCurrentLocation
-                      .image(width: 20.w, height: 20.w),
+                  child: Assets.images.iconMainLocation
+                      .image(width: 24.w, height: 24.w),
                 )),
           ),
         ),

+ 39 - 0
lib/module/main/main_common_view.dart

@@ -0,0 +1,39 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:location/resource/colors.gen.dart';
+
+Widget buildMainFunctionView(ImageProvider icon, String name,
+    {VoidCallback? onTap}) {
+  return GestureDetector(
+    onTap: onTap,
+    child: Container(
+      width: 42.w,
+      height: 42.w,
+      decoration: BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.circular(10.w),
+        boxShadow: [
+          BoxShadow(
+            color: ColorName.black5.withOpacity(0.06),
+            blurRadius: 10,
+            spreadRadius: 6,
+            offset: const Offset(0, 0),
+          ),
+        ],
+      ),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: [
+          Image(image: icon, width: 24.w, height: 24.w),
+          if (name.isNotEmpty)
+            Text(name,
+                style: TextStyle(
+                    fontSize: 9.sp,
+                    color: ColorName.black90,
+                    fontWeight: FontWeight.bold))
+        ],
+      ),
+    ),
+  );
+}

+ 29 - 10
lib/module/main/main_controller.dart

@@ -1,5 +1,6 @@
 import 'dart:async';
 import 'dart:io';
+import 'package:flutter/cupertino.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_map/flutter_map.dart';
 import 'package:flutter_tool_android/flutter_tool_android.dart';
@@ -49,7 +50,7 @@ import '../track/track_page.dart';
 
 @injectable
 class MainController extends BaseController {
-  RxList<UserInfo> get _friendsList => friendsRepository.friendsList;
+  RxList<UserInfo> get friendsList => friendsRepository.friendsList;
 
   Rxn<MemberStatusInfo> get memberStatusInfo =>
       accountRepository.memberStatusInfo;
@@ -100,6 +101,12 @@ class MainController extends BaseController {
 
   final Map<String, int> electricMap = {};
 
+  final RxDouble _sheetProgress = 0.0.obs;
+
+  double get sheetProgress => _sheetProgress.value;
+
+  final PageController pageController = PageController();
+
   RxMap<String, TodayTrackReportBean> get todayTrackReportMap =>
       todayTrackHelper.todayTrackReportMap;
 
@@ -138,9 +145,9 @@ class MainController extends BaseController {
       }
     });
     //刷新好友列表
-    _updateFriendList(_friendsList);
+    _updateFriendList(friendsList);
     friendsListSubscription =
-        _friendsList.listen((list) => _updateFriendList(list));
+        friendsList.listen((list) => _updateFriendList(list));
 
     //刷新我的marker
     updateMineInfo(accountRepository.mineUserInfo.value);
@@ -162,7 +169,7 @@ class MainController extends BaseController {
     memberStatusInfoSubscription =
         accountRepository.memberStatusInfo.listen((memberStatus) {
       if (memberStatus != null) {
-        _updateFriendList(_friendsList);
+        _updateFriendList(friendsList);
       }
     });
 
@@ -325,12 +332,13 @@ class MainController extends BaseController {
 
   void onMarkerTap(Marker marker) {
     String id = marker.id;
-    UserInfo? userInfo =
-        integrateList.firstWhereOrNull((element) => element.id == id);
-    if (userInfo == null) {
-      return;
+    for (int i = 0; i < integrateList.length; i++) {
+      final value = integrateList[i];
+      if (value.id == id) {
+        pageController.jumpToPage(i);
+        return;
+      }
     }
-    onSelectUserClick(userInfo);
   }
 
   void onCurrentLocationClick() async {
@@ -504,9 +512,11 @@ class MainController extends BaseController {
       isExecuteAutoSelect = true;
       return;
     }
-    for (var value in integrateList) {
+    for (int i = 0; i < integrateList.length; i++) {
+      final value = integrateList[i];
       if (value.id == lastCheckFriendId) {
         isExecuteAutoSelect = true;
+        pageController.jumpToPage(i);
         _setSelectUserInfo(value);
         return;
       }
@@ -550,6 +560,15 @@ class MainController extends BaseController {
         lastSelectedGoods!, memberRepository.lastSelectedPayItem!);
   }
 
+  setSheetProgress(double progress) {
+    _sheetProgress.value = progress;
+  }
+
+  void onFriendPageChanged(int pageIndex) {
+    final userInfo = integrateList[pageIndex];
+    onSelectUserClick(userInfo);
+  }
+
   @override
   void onClose() {
     mineLocationSubscription?.cancel();

+ 151 - 3
lib/module/main/main_friend_item.dart

@@ -3,12 +3,162 @@ import 'dart:ui';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get_rx/src/rx_types/rx_types.dart';
+import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
+import 'package:location/data/bean/member_status_info.dart';
 import 'package:location/data/bean/user_info.dart';
 import 'package:location/resource/colors.gen.dart';
 import 'package:location/utils/common_expand.dart';
+import '../../data/consts/constants.dart';
+import '../../resource/assets.gen.dart';
+import '../../resource/string.gen.dart';
 import '../../utils/common_style.dart';
 import '../../utils/common_util.dart';
 import '../../widget/marquee_text.dart';
+import '../../widget/relative_time_text.dart';
+
+typedef OnViewTraceClick = void Function(UserInfo userInfo);
+
+Widget buildSelectFriendInfoView(
+    UserInfo userInfo, Rxn<MemberStatusInfo> memberStatusInfo,
+    {OnViewTraceClick? onTraceClick}) {
+  return Container(
+      width: 336.w,
+      height: 68.h,
+      decoration: BoxDecoration(
+          color: ColorName.white,
+          borderRadius: BorderRadius.all(Radius.circular(10.r))),
+      child: Stack(
+        children: [
+          Positioned(
+              top: 0,
+              bottom: 0,
+              right: 0,
+              child: Assets.images.bgMainFriendCard
+                  .image(height: double.infinity)),
+          Row(
+            children: [
+              SizedBox(width: 12.w),
+              Container(
+                width: 38.w,
+                height: 38.w,
+                decoration: BoxDecoration(
+                    shape: BoxShape.circle,
+                    border: Border.all(color: ColorName.black5, width: 0.5.w)),
+                child: buildCustomAvatarOrDefaultAvatarView(
+                    size: double.infinity,
+                    avatar: userInfo.avatar,
+                    isMine: userInfo.isMine == true),
+              ),
+              SizedBox(width: 5.w),
+              Expanded(
+                child: Column(
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Spacer(),
+                    Row(
+                      children: [
+                        ConstrainedBox(
+                          constraints: BoxConstraints(
+                            maxWidth: 0.26.sw,
+                          ),
+                          child: Text(
+                            maxLines: 1,
+                            userInfo.getUserNickName(),
+                            overflow: TextOverflow.ellipsis,
+                            style: TextStyle(
+                                fontWeight: FontWeight.bold,
+                                fontSize: 14.sp,
+                                color: '#202020'.color),
+                          ),
+                        ),
+                        SizedBox(width: 8.w),
+                        Obx(() {
+                          return RelativeTimeText(
+                              timestamp:
+                                  userInfo.lastLocation.value?.lastUpdateTime,
+                              updateInterval: Duration(minutes: 1),
+                              style: TextStyle(
+                                  fontSize: 11.sp, color: ColorName.black30));
+                        })
+                      ],
+                    ),
+                    SizedBox(height: 5.w),
+                    Expanded(
+                      child: Container(
+                        margin: EdgeInsets.only(right: 12.w),
+                        child: Obx(() {
+                          return ImageFiltered(
+                            enabled: userInfo.blockedMe == true ||
+                                ((memberStatusInfo.value == null ||
+                                        memberStatusInfo.value?.expired ==
+                                            true) &&
+                                    !(userInfo.isMine == true)),
+                            imageFilter: ImageFilter.blur(
+                              sigmaX: Constants.blurredX,
+                              sigmaY: Constants.blurredY,
+                            ),
+                            child: userInfo.blockedMe == true ||
+                                    ((memberStatusInfo.value == null ||
+                                            memberStatusInfo.value?.expired ==
+                                                true) &&
+                                        !(userInfo.isMine == true))
+                                ? Text(
+                                    addressCheck(
+                                        userInfo.lastLocation.value?.address),
+                                    style: TextStyle(
+                                        fontSize: 12.sp,
+                                        color: ColorName.black50))
+                                : MarqueeText(
+                                    text: addressCheck(
+                                        userInfo.lastLocation.value?.address),
+                                    textStyle: TextStyle(
+                                        fontSize: 12.sp,
+                                        color: ColorName.black50)),
+                          );
+                        }),
+                      ),
+                    ),
+                    Spacer(),
+                  ],
+                ),
+              ),
+              GestureDetector(
+                onTap: () {
+                  onTraceClick?.call(userInfo);
+                },
+                child: Container(
+                    decoration: BoxDecoration(
+                        borderRadius: BorderRadius.circular(8.w),
+                        gradient: LinearGradient(
+                            stops: [0.6, 1],
+                            begin: Alignment.topLeft,
+                            end: Alignment.bottomRight,
+                            colors: [
+                              '#6567EA'.color,
+                              '#41E3C5'.color,
+                            ])),
+                    margin: EdgeInsets.only(right: 12.w),
+                    padding:
+                        EdgeInsets.symmetric(horizontal: 10.w, vertical: 8.w),
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        Assets.images.iconMainTrackLocation
+                            .image(width: 8.w, height: 8.w),
+                        SizedBox(width: 2.w),
+                        Text(StringName.locationTrace,
+                            style:
+                                TextStyle(fontSize: 11.sp, color: Colors.white))
+                      ],
+                    )),
+              ),
+            ],
+          )
+        ],
+      ));
+}
 
 Widget mainFriendItem(UserInfo userInfo, bool isSelected,
     {required VoidCallback onTap}) {
@@ -51,9 +201,8 @@ Widget mainFriendItem(UserInfo userInfo, bool isSelected,
                     TextStyle(fontSize: 10.sp, color: ColorName.black80);
                 return Center(
                   child: isSelected
-                      ? MarqueeText.marquee(
+                      ? MarqueeText(
                           text: nickName,
-                          containerWidth: 45.w,
                           textStyle: TextStyle(
                               fontSize: 10.sp, color: ColorName.black80))
                       : Text(nickName, style: style),
@@ -66,4 +215,3 @@ Widget mainFriendItem(UserInfo userInfo, bool isSelected,
     ),
   );
 }
-

+ 226 - 318
lib/module/main/main_page.dart

@@ -19,12 +19,14 @@ import 'package:location/widget/shimmer_effect.dart';
 import 'package:sliding_sheet2/sliding_sheet2.dart';
 import 'package:visibility_detector/visibility_detector.dart';
 import '../../data/consts/constants.dart';
+import '../../resource/fonts.gen.dart';
 import '../../router/app_pages.dart';
 import '../../utils/common_style.dart';
 import '../../utils/common_util.dart';
 import '../../widget/activity_countdown_txt_view.dart';
 import '../../widget/marquee_text.dart';
 import '../../widget/relative_time_text.dart';
+import 'main_common_view.dart';
 import 'main_friend_item.dart';
 
 class MainPage extends BasePage<MainController> {
@@ -50,23 +52,65 @@ class MainPage extends BasePage<MainController> {
       onPopInvokedWithResult: (bool didPop, dynamic result) {
         controller.onAppBack();
       },
-      child: Column(
+      child: Stack(
         children: [
-          Expanded(
-              child: Stack(
-            children: [
-              buildMapView(),
-              buildMapFunView(),
-              buildMainBottomView(),
-              buildFriendListView(),
-            ],
-          )),
-          buildTabContainer()
+          buildMapView(),
+          buildMainCaringReportView(),
+          buildMainFunView(),
+          buildMapFunView(),
+          buildMapLogoView(),
+          buildMainSlidingSheetView(),
         ],
       ),
     );
   }
 
+  Widget buildMainFunView() {
+    return Positioned(
+      right: 12.w,
+      top: 35.w,
+      child: SafeArea(
+        child: Column(
+          children: [
+            Container(
+                child: buildMainFunctionView(
+                    Assets.images.iconMainMine.provider(),
+                    StringName.mainTabMine,
+                    onTap: controller.onMineClick)),
+            SizedBox(height: 20.w),
+            Container(
+                child: buildMainFunctionView(
+                    Assets.images.iconMainFriend.provider(),
+                    StringName.mainTabFriend,
+                    onTap: controller.onFriendClick)),
+            SizedBox(height: 20.w),
+            Container(
+                child: buildMainFunctionView(
+                    Assets.images.iconMainNews.provider(),
+                    StringName.mainTabNews,
+                    onTap: controller.onNewsClick)),
+            SizedBox(height: 20.w),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget buildMainCaringReportView() {
+    return Positioned(
+      left: -8.w,
+      top: 6.w,
+      child: SafeArea(
+          child: SizedBox(
+        width: 210.w,
+        child: AspectRatio(
+          aspectRatio: 187 / 69,
+          child: Assets.images.imgMainCaringReport.image(),
+        ),
+      )),
+    );
+  }
+
   Widget buildMapView() {
     return Padding(
       padding: EdgeInsets.only(bottom: 50.h),
@@ -79,7 +123,7 @@ class MainPage extends BasePage<MainController> {
     );
   }
 
-  Widget buildMainBottomView() {
+  Widget buildMainSlidingSheetView() {
     return Obx(() {
       if (controller.lastSelectedGoods == null) {
         return buildSlidingSheet(false);
@@ -91,6 +135,9 @@ class MainPage extends BasePage<MainController> {
 
   SlidingSheet buildSlidingSheet(bool isShowActivity) {
     return SlidingSheet(
+      listener: (SheetState state) {
+        controller.setSheetProgress(state.progress);
+      },
       key: Key(isShowActivity ? 'activity_view' : 'not_activity_view'),
       color: ColorName.transparent,
       snapSpec: SnapSpec(
@@ -118,7 +165,7 @@ class MainPage extends BasePage<MainController> {
         controller.onFriendVisibleFraction(visibleFraction);
       },
       child: Container(
-        color: '#F9F9F9'.color,
+        color: '#EFF4FC'.color,
         child: AspectRatio(
           aspectRatio: 336 / 134,
           child: Container(
@@ -317,49 +364,49 @@ class MainPage extends BasePage<MainController> {
         ));
   }
 
-  Widget buildFriendListView() {
-    return SafeArea(
-      child: Container(
-        margin: EdgeInsets.only(top: 26.w),
-        child: Row(
-          children: [
-            Expanded(child: buildMainFriendList()),
-            GestureDetector(
-              onTap: () {
-                controller.onAddFriendClick();
-              },
-              child: Container(
-                  margin: EdgeInsets.only(right: 16.w, left: 8.w),
-                  child: Assets.images.iconMainAddFriend
-                      .image(width: 60.w, height: 60.w)),
-            )
-          ],
-        ),
-      ),
+  Widget buildMapLogoView() {
+    return Visibility(
+      visible: Platform.isAndroid,
+      child: Obx(() {
+        return Positioned(
+            left: 12.w,
+            bottom: 136.w +
+                (controller.lastSelectedGoods != null ? 64.w : 0) +
+                controller.sheetProgress * 143.w,
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                Assets.images.iconAmapLogo.image(height: 20.w),
+                Text(StringName.locationAmapCo,
+                    style: TextStyle(
+                        fontSize: 9.sp, color: '#666666'.color, height: 1))
+              ],
+            ));
+      }),
     );
   }
 
   Widget buildMapFunView() {
     return Obx(() {
       return Positioned(
-        right: 0.w,
-        bottom: controller.lastSelectedGoods == null ? 140.w : 180.w,
+        right: 12.w,
+        bottom: 110.w +
+            (controller.lastSelectedGoods != null ? 64.w : 0) +
+            controller.sheetProgress * 143.w,
         child: Column(
           children: [
             GestureDetector(
               onTap: controller.onRefreshFriendLocationClick,
-              child: Container(
-                  margin: EdgeInsets.only(right: 12.w),
-                  child: Assets.images.iconMainRefreshFriendLocation
-                      .image(width: 42.w, height: 42.w)),
+              child: buildMainFunctionView(
+                  Assets.images.iconMainRefresh.provider(), '',
+                  onTap: controller.onRefreshFriendLocationClick),
             ),
-            SizedBox(height: 14.w),
+            SizedBox(height: 20.w),
             GestureDetector(
               onTap: controller.onCurrentLocationClick,
-              child: Container(
-                  margin: EdgeInsets.only(right: 12.w),
-                  child: Assets.images.iconMainRefreshMineLocation
-                      .image(width: 42.w, height: 42.w)),
+              child: buildMainFunctionView(
+                  Assets.images.iconMainLocation.provider(), '',
+                  onTap: controller.onCurrentLocationClick),
             ),
             SizedBox(height: 20.w)
           ],
@@ -368,63 +415,6 @@ class MainPage extends BasePage<MainController> {
     });
   }
 
-  Container buildTabContainer() {
-    return Container(
-        decoration: BoxDecoration(
-          color: ColorName.white,
-          borderRadius: BorderRadius.only(
-            topLeft: Radius.circular(20.w),
-            topRight: Radius.circular(20.w),
-          ),
-          boxShadow: [
-            BoxShadow(
-              color: ColorName.black.withOpacity(0.01),
-              blurRadius: 10,
-              offset: const Offset(0, -2), // changes position of shadow
-            ),
-          ],
-        ),
-        padding: EdgeInsets.only(top: 13.w, bottom: 23.w),
-        child: buildMainFunList());
-  }
-
-  Widget buildMainFunList() {
-    return Row(
-      children: [
-        Expanded(
-            child: buildFunItem(
-                Platform.isIOS
-                    ? Assets.images.iconMainFriendGuard.provider()
-                    : Assets.images.iconMainFriendGuardAndroid.provider(),
-                StringName.mainFriendListTab,
-                () => controller.onFriendClick())),
-        Expanded(child: Obx(() {
-          return buildFunItem(
-              Platform.isIOS
-                  ? Assets.images.iconMainNews.provider()
-                  : Assets.images.iconMainNewsAndroid.provider(),
-              StringName.mainNewsTab,
-              () => controller.onNewsClick(),
-              isShowDot: controller.hasUnreadMessage);
-        })),
-        Expanded(
-            child: buildFunItem(
-                Platform.isIOS
-                    ? Assets.images.iconMainHelp.provider()
-                    : Assets.images.iconMainHelpAndroid.provider(),
-                StringName.mainHelpTab,
-                () => controller.onUrgentContactClick())),
-        Expanded(
-            child: buildFunItem(
-                Platform.isIOS
-                    ? Assets.images.iconMainMine.provider()
-                    : Assets.images.iconMainMineAndroid.provider(),
-                StringName.mainMineTab,
-                () => controller.onMineClick()))
-      ],
-    );
-  }
-
   Widget buildFunItem(ImageProvider imgProvider, String title, Function() onTap,
       {bool? isShowDot}) {
     return GestureDetector(
@@ -462,100 +452,136 @@ class MainPage extends BasePage<MainController> {
     );
   }
 
-  Widget buildMainFriendList() {
-    return SizedBox(
-      height: 58.w,
-      child: Obx(() {
-        return ListView(
-          physics: const BouncingScrollPhysics(
-              parent: AlwaysScrollableScrollPhysics()),
-          padding: EdgeInsets.only(left: 12.w),
-          scrollDirection: Axis.horizontal,
-          children: [
-            for (UserInfo userInfo in controller.integrateList)
-              Obx(() {
-                return mainFriendItem(
-                    userInfo, controller.selectedFriend?.id == userInfo.id,
-                    onTap: () {
-                  controller.onSelectUserClick(userInfo);
-                });
-              })
-          ],
-        );
-      }),
-    );
-  }
-
-  Widget buildFooterBuilder(BuildContext context, SheetState state) {
-    return buildTabContainer();
-  }
-
   Widget buildHeaderBuilder(BuildContext context, SheetState state) {
     return buildHeaderView(false);
   }
 
   Widget buildHeaderView(bool isShowActivity) {
     return IntrinsicHeight(
-      child: Stack(
-        alignment: Alignment.topCenter,
-        children: [
-          Visibility(
-            visible: isShowActivity,
-            child: Assets.images.bgMemberActivityMain
-                .image(width: 336.w, height: 67.w),
-          ),
-          Visibility(visible: isShowActivity, child: buildActivityMemberView()),
-          Column(
+        child: Column(
+      children: [
+        Visibility(visible: isShowActivity, child: buildActivityMemberView()),
+        buildSelectFriendPlateView()
+      ],
+    ));
+  }
+
+  Widget buildSelectFriendPlateView() {
+    return Container(
+      width: double.infinity,
+      padding: EdgeInsets.only(left: 1.5.w, top: 1.5.w, right: 1.5.w),
+      decoration: BoxDecoration(
+          borderRadius: BorderRadius.only(
+              topLeft: Radius.circular(12.r), topRight: Radius.circular(12.r)),
+          gradient: LinearGradient(
+              begin: Alignment.topCenter,
+              end: Alignment.bottomCenter,
+              colors: [
+                Colors.white,
+                '#EFF4FC'.color,
+              ])),
+      child: Container(
+          width: double.infinity,
+          decoration: BoxDecoration(
+              color: '#EFF4FC'.color,
+              borderRadius: BorderRadius.only(
+                  topLeft: Radius.circular(12.w),
+                  topRight: Radius.circular(12.w))),
+          child: Column(
             children: [
-              Visibility(
-                  visible: isShowActivity, child: SizedBox(height: 58.w)),
+              SizedBox(height: 7.h),
               Container(
-                width: double.infinity,
+                width: 24.w,
+                height: 3.h,
+                decoration: BoxDecoration(
+                    color: '#CDE0FF'.color,
+                    borderRadius: BorderRadius.all(Radius.circular(49.w))),
+              ),
+              SizedBox(height: 5.h),
+              buildFriendPlateListView(),
+              SizedBox(height: 12.h)
+            ],
+          )),
+    );
+  }
+
+  Widget buildFriendPlateListView() {
+    return SizedBox(
+      width: double.infinity,
+      height: 68.h,
+      child: Row(
+        children: [
+          Expanded(child: Obx(() {
+            return PageView.builder(
+                controller: controller.pageController,
+                onPageChanged: controller.onFriendPageChanged,
+                physics: const BouncingScrollPhysics(),
+                itemBuilder: (ctx, index) =>
+                    _buildFriendListItem(controller.integrateList[index]),
+                itemCount: controller.integrateList.length);
+          })),
+          Obx(() {
+            return Visibility(
+              visible: controller.friendsList.isNotEmpty,
+              child: Container(
+                padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 6.w),
                 decoration: BoxDecoration(
-                  color: '#F9F9F9'.color,
+                  color: Colors.white,
                   borderRadius: BorderRadius.only(
-                    topLeft: Radius.circular(20.w),
-                    topRight: Radius.circular(20.w),
-                  ),
-                  boxShadow: [
-                    BoxShadow(
-                      color: ColorName.black.withOpacity(0.01),
-                      blurRadius: 10,
-                      offset: const Offset(0, -2), // changes position of shadow
-                    ),
-                  ],
+                      topLeft: Radius.circular(10.r),
+                      bottomLeft: Radius.circular(10.r)),
                 ),
-                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)
-                  ],
+                child: IntrinsicHeight(
+                  child: Column(
+                    children: [
+                      Text(StringName.mainLeftSlipSwitch,
+                          style: TextStyle(
+                              fontSize: 8.sp,
+                              color: ColorName.colorPrimary,
+                              fontWeight: FontWeight.bold)),
+                      SizedBox(height: 2.w),
+                      Assets.images.iconMainLeftSlipArrow
+                          .image(width: 5.w, height: 5.w)
+                    ],
+                  ),
                 ),
-              )
-            ],
-          )
+              ),
+            );
+          })
         ],
       ),
     );
   }
 
+  Widget _buildFriendListItem(UserInfo userInfo) {
+    return Obx(() {
+      return Padding(
+        padding: EdgeInsets.only(
+            left: 12.w, right: controller.friendsList.isNotEmpty ? 8.w : 12.w),
+        child: buildSelectFriendInfoView(userInfo, controller.memberStatusInfo,
+            onTraceClick: controller.onViewTraceClick),
+      );
+    });
+  }
+
   Widget buildActivityMemberView() {
     return GestureDetector(
       behavior: HitTestBehavior.opaque,
       onTap: controller.onBuyMemberActivityClick,
       child: Container(
-        height: 58.w,
-        margin: EdgeInsets.only(left: 12.w, right: 12.w),
+        height: 56.w,
+        margin: EdgeInsets.only(left: 12.w, right: 12.w, bottom: 8.w),
+        decoration: BoxDecoration(
+            borderRadius: BorderRadius.all(Radius.circular(12.r)),
+            gradient: LinearGradient(
+              colors: [
+                '#FFEEE9'.color,
+                Colors.white,
+              ],
+              stops: [0.0, 0.8],
+              begin: Alignment.topCenter,
+              end: Alignment.bottomCenter,
+            )),
         child: ShimmerEffect(
             image: Assets.images.imgMemberBtnShadow.provider(),
             child: Stack(
@@ -575,38 +601,39 @@ class MainPage extends BasePage<MainController> {
                             Text('您有一订单未支付专属优惠券',
                                 style: TextStyle(
                                     fontSize: 10.sp,
-                                    color: ColorName.white87,
+                                    color: '#202020'.color,
                                     fontWeight: FontWeight.bold)),
                             Obx(() {
                               return Text(
                                   ' -¥${(((controller.lastSelectedGoods?.originalAmount ?? 0) - (controller.lastSelectedGoods?.amount ?? 0)) / 100).toInt()}',
                                   style: TextStyle(
                                       fontSize: 20.sp,
-                                      color: '#E7DBA7'.color,
+                                      color: '#E74E4E'.color,
                                       fontWeight: FontWeight.bold));
                             })
                           ],
                         ),
                         Row(
+                          crossAxisAlignment: CrossAxisAlignment.start,
                           children: [
                             Obx(() {
                               return ActivityCountdownTextView(
                                   timeItemHeight: 15.w,
-                                  contentPadding: EdgeInsets.zero,
-                                  timeItemWidth: 16.w,
+                                  contentPadding:
+                                      EdgeInsets.symmetric(horizontal: 2.w),
                                   textStyle: TextStyle(
-                                      fontSize: 10.sp, color: '#322C54'.color),
+                                    fontSize: 11.sp,
+                                    color: '#E74F4F'.color,
+                                    fontWeight: FontWeight.w500,
+                                  ),
                                   duration: controller.activityDuration ??
                                       Duration(seconds: 0),
                                   separator: buildCountdownSeparator(),
                                   timeBgBoxDecoration: BoxDecoration(
-                                    gradient: LinearGradient(
-                                        colors: [
-                                          ColorName.white,
-                                          ColorName.white87
-                                        ],
-                                        begin: Alignment.topCenter,
-                                        end: Alignment.bottomCenter),
+                                    gradient: LinearGradient(colors: [
+                                      '#FFEFEF'.color,
+                                      '#FFEFEF'.color,
+                                    ]),
                                     borderRadius: BorderRadius.circular(3.w),
                                   ));
                             }),
@@ -614,9 +641,9 @@ class MainPage extends BasePage<MainController> {
                             Text(
                               StringName.memberActivitySpeciallyPreferential,
                               style: TextStyle(
-                                  fontSize: 10.sp,
-                                  color: ColorName.white87,
-                                  fontWeight: FontWeight.bold),
+                                fontSize: 10.sp,
+                                color: '#202020'.color,
+                              ),
                             )
                           ],
                         ),
@@ -631,21 +658,21 @@ class MainPage extends BasePage<MainController> {
                   right: 10.w,
                   child: Container(
                       decoration: BoxDecoration(
-                        borderRadius: BorderRadius.circular(100.w),
+                        borderRadius: BorderRadius.circular(8.w),
                         gradient: LinearGradient(
-                            colors: [
-                              '#FFFEF3'.color,
-                              '#FFE5A3'.color,
-                            ],
-                            begin: Alignment.topCenter,
-                            end: Alignment.bottomCenter),
+                          colors: [
+                            '#FA6565'.color,
+                            '#D565FA'.color,
+                          ],
+                        ),
                       ),
-                      padding: EdgeInsets.symmetric(horizontal: 12.w),
+                      padding:
+                          EdgeInsets.symmetric(horizontal: 14.w, vertical: 7.w),
                       child: Center(
                         child: Text(StringName.memberActivityToBuy,
                             style: TextStyle(
-                                fontSize: 14.sp,
-                                color: '#40338B'.color,
+                                fontSize: 12.sp,
+                                color: Colors.white,
                                 height: 1,
                                 fontWeight: FontWeight.bold)),
                       )),
@@ -666,7 +693,7 @@ class MainPage extends BasePage<MainController> {
               width: 2.w,
               height: 2.w,
               decoration: BoxDecoration(
-                color: ColorName.white87,
+                color: '#E74F4F'.color,
                 shape: BoxShape.circle,
               ),
             ),
@@ -675,7 +702,7 @@ class MainPage extends BasePage<MainController> {
               width: 2.w,
               height: 2.w,
               decoration: BoxDecoration(
-                color: ColorName.white87,
+                color: '#E74F4F'.color,
                 shape: BoxShape.circle,
               ),
             )
@@ -684,123 +711,4 @@ class MainPage extends BasePage<MainController> {
       ),
     );
   }
-
-  Widget buildSelectFriendInfoView() {
-    return Container(
-        width: 336.w,
-        height: 86.w,
-        decoration: BoxDecoration(
-            color: ColorName.white,
-            borderRadius: BorderRadius.all(Radius.circular(20.w))),
-        child: Row(
-          children: [
-            SizedBox(width: 7.w),
-            Obx(() {
-              return buildCustomAvatarOrDefaultAvatarView(
-                  size: 50.w,
-                  avatar: controller.selectedFriend?.avatar,
-                  isMine: controller.selectedFriend?.isMine == true);
-            }),
-            SizedBox(width: 5.w),
-            Expanded(
-              child: Container(
-                margin: EdgeInsets.symmetric(vertical: 15.w),
-                child: Column(
-                  mainAxisAlignment: MainAxisAlignment.center,
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    Row(
-                      children: [
-                        Obx(() {
-                          return ConstrainedBox(
-                            constraints: BoxConstraints(
-                              maxWidth: 0.26.sw,
-                            ),
-                            child: Text(
-                              maxLines: 1,
-                              controller.selectedFriend?.getUserNickName() ??
-                                  '',
-                              overflow: TextOverflow.ellipsis,
-                              style: TextStyle(
-                                  fontWeight: FontWeight.bold,
-                                  fontSize: 16.sp,
-                                  color: '#202020'.color),
-                            ),
-                          );
-                        }),
-                        SizedBox(width: 7.w),
-                        Obx(() {
-                          return RelativeTimeText(
-                              timestamp: controller.selectedFriend?.lastLocation
-                                  .value?.lastUpdateTime,
-                              updateInterval: Duration(minutes: 1),
-                              style: TextStyle(
-                                  fontSize: 12.sp, color: '#A7A7A7'.color));
-                        }),
-                        Spacer(),
-                        Obx(() {
-                          return controller.selectedFriend != null
-                              ? GestureDetector(
-                                  onTap: () => controller.onViewTraceClick(
-                                      controller.selectedFriend!),
-                                  child: Container(
-                                      margin: EdgeInsets.only(right: 12.w),
-                                      decoration: getPrimaryBtnDecoration(32.w),
-                                      padding: EdgeInsets.symmetric(
-                                          horizontal: 21.w, vertical: 5.w),
-                                      child: Text(StringName.locationTrace,
-                                          style: TextStyle(
-                                              fontSize: 15.sp,
-                                              color: Colors.white))),
-                                )
-                              : SizedBox.shrink();
-                        }),
-                      ],
-                    ),
-                    Expanded(
-                      child: Container(
-                        margin: EdgeInsets.only(right: 17.w),
-                        child: Obx(() {
-                          return ImageFiltered(
-                            enabled: controller.selectedFriend?.blockedMe ==
-                                    true ||
-                                ((controller.memberStatusInfo.value == null ||
-                                        controller.memberStatusInfo.value
-                                                ?.expired ==
-                                            true) &&
-                                    !(controller.selectedFriend?.isMine ==
-                                        true)),
-                            imageFilter: ImageFilter.blur(
-                              sigmaX: Constants.blurredX,
-                              sigmaY: Constants.blurredY,
-                            ),
-                            child: controller.selectedFriend?.blockedMe == true ||
-                                    ((controller.memberStatusInfo.value == null ||
-                                            controller.memberStatusInfo.value?.expired ==
-                                                true) &&
-                                        !(controller.selectedFriend?.isMine ==
-                                            true))
-                                ? Text(addressCheck(controller.selectedFriend?.lastLocation.value?.address),
-                                    style: TextStyle(
-                                        fontSize: 13.sp,
-                                        color: ColorName.black50))
-                                : MarqueeText.marquee(
-                                    text: addressCheck(controller.selectedFriend
-                                        ?.lastLocation.value?.address),
-                                    textStyle: TextStyle(
-                                        fontSize: 13.sp,
-                                        color: ColorName.black50),
-                                    containerWidth: 244.w),
-                          );
-                        }),
-                      ),
-                    )
-                    // Text('广东省广州市天河区XX街街XX街区XX村XX')
-                  ],
-                ),
-              ),
-            )
-          ],
-        ));
-  }
 }

+ 0 - 1
lib/module/member/activity/member_activity_page.dart

@@ -18,7 +18,6 @@ import 'package:location/utils/project_expand.dart';
 import '../../../resource/fonts.gen.dart';
 import '../../../router/app_pages.dart';
 import '../../../widget/activity_countdown_txt_view.dart';
-import '../../../widget/activity_countdown_view.dart';
 import '../../../widget/shimmer_effect.dart';
 import 'member_activity_controller.dart';
 

+ 2 - 2
lib/module/member/member_page.dart

@@ -484,8 +484,8 @@ class MemberPage extends BasePage<MemberController> {
                                   Obx(() {
                                     return ActivityCountdownTextView(
                                         timeItemHeight: 15.w,
-                                        contentPadding: EdgeInsets.zero,
-                                        timeItemWidth: 16.w,
+                                        contentPadding: EdgeInsets.symmetric(
+                                            horizontal: 2.w),
                                         textStyle: TextStyle(
                                             fontSize: 10.sp,
                                             color: Colors.white),

+ 31 - 46
lib/resource/assets.gen.dart

@@ -79,6 +79,10 @@ class $AssetsImagesGen {
   AssetGenImage get bgLoginHeadContainer =>
       const AssetGenImage('assets/images/bg_login_head_container.webp');
 
+  /// File path: assets/images/bg_main_friend_card.webp
+  AssetGenImage get bgMainFriendCard =>
+      const AssetGenImage('assets/images/bg_main_friend_card.webp');
+
   /// File path: assets/images/bg_member_activity.webp
   AssetGenImage get bgMemberActivity =>
       const AssetGenImage('assets/images/bg_member_activity.webp');
@@ -87,10 +91,6 @@ class $AssetsImagesGen {
   AssetGenImage get bgMemberActivityContainer =>
       const AssetGenImage('assets/images/bg_member_activity_container.webp');
 
-  /// File path: assets/images/bg_member_activity_main.webp
-  AssetGenImage get bgMemberActivityMain =>
-      const AssetGenImage('assets/images/bg_member_activity_main.webp');
-
   /// File path: assets/images/bg_member_header.webp
   AssetGenImage get bgMemberHeader =>
       const AssetGenImage('assets/images/bg_member_header.webp');
@@ -215,10 +215,6 @@ class $AssetsImagesGen {
   AssetGenImage get iconCommonPointSearch =>
       const AssetGenImage('assets/images/icon_common_point_search.webp');
 
-  /// File path: assets/images/icon_current_location.webp
-  AssetGenImage get iconCurrentLocation =>
-      const AssetGenImage('assets/images/icon_current_location.webp');
-
   /// File path: assets/images/icon_date_selected.webp
   AssetGenImage get iconDateSelected =>
       const AssetGenImage('assets/images/icon_date_selected.webp');
@@ -327,45 +323,29 @@ class $AssetsImagesGen {
   AssetGenImage get iconLogoMax =>
       const AssetGenImage('assets/images/icon_logo_max.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_friend_guard_android.webp
-  AssetGenImage get iconMainFriendGuardAndroid =>
-      const AssetGenImage('assets/images/icon_main_friend_guard_android.webp');
+  /// File path: assets/images/icon_main_friend.webp
+  AssetGenImage get iconMainFriend =>
+      const AssetGenImage('assets/images/icon_main_friend.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_left_slip_arrow.webp
+  AssetGenImage get iconMainLeftSlipArrow =>
+      const AssetGenImage('assets/images/icon_main_left_slip_arrow.webp');
 
-  /// File path: assets/images/icon_main_help_android.webp
-  AssetGenImage get iconMainHelpAndroid =>
-      const AssetGenImage('assets/images/icon_main_help_android.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_location.webp
+  AssetGenImage get iconMainLocation =>
+      const AssetGenImage('assets/images/icon_main_location.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_mine_android.webp
-  AssetGenImage get iconMainMineAndroid =>
-      const AssetGenImage('assets/images/icon_main_mine_android.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_news_android.webp
-  AssetGenImage get iconMainNewsAndroid =>
-      const AssetGenImage('assets/images/icon_main_news_android.webp');
+  /// File path: assets/images/icon_main_refresh.webp
+  AssetGenImage get iconMainRefresh =>
+      const AssetGenImage('assets/images/icon_main_refresh.webp');
 
   /// File path: assets/images/icon_main_refresh_friend_location.webp
   AssetGenImage get iconMainRefreshFriendLocation => const AssetGenImage(
@@ -379,6 +359,10 @@ class $AssetsImagesGen {
   AssetGenImage get iconMainTrackArrow =>
       const AssetGenImage('assets/images/icon_main_track_arrow.webp');
 
+  /// File path: assets/images/icon_main_track_location.webp
+  AssetGenImage get iconMainTrackLocation =>
+      const AssetGenImage('assets/images/icon_main_track_location.webp');
+
   /// File path: assets/images/icon_member_activity_close.webp
   AssetGenImage get iconMemberActivityClose =>
       const AssetGenImage('assets/images/icon_member_activity_close.webp');
@@ -751,6 +735,10 @@ class $AssetsImagesGen {
   AssetGenImage get imgDialogLocationAlwaysTip3 => const AssetGenImage(
       'assets/images/img_dialog_location_always_tip_3.webp');
 
+  /// File path: assets/images/img_main_caring_report.webp
+  AssetGenImage get imgMainCaringReport =>
+      const AssetGenImage('assets/images/img_main_caring_report.webp');
+
   /// File path: assets/images/img_member_activity_banner_1.webp
   AssetGenImage get imgMemberActivityBanner1 =>
       const AssetGenImage('assets/images/img_member_activity_banner_1.webp');
@@ -839,9 +827,9 @@ class $AssetsImagesGen {
         bgLocationAnalyse,
         bgLocationAnalyseAi,
         bgLoginHeadContainer,
+        bgMainFriendCard,
         bgMemberActivity,
         bgMemberActivityContainer,
-        bgMemberActivityMain,
         bgMemberHeader,
         bgMineMemberCard,
         bgPageBackground,
@@ -873,7 +861,6 @@ class $AssetsImagesGen {
         iconCommonPointAiSummary,
         iconCommonPointNoData,
         iconCommonPointSearch,
-        iconCurrentLocation,
         iconDateSelected,
         iconDateUnSelect,
         iconDefaultFriendAvatar,
@@ -901,19 +888,16 @@ class $AssetsImagesGen {
         iconLoginWx,
         iconLogo,
         iconLogoMax,
-        iconMainAddFriend,
-        iconMainFriendGuard,
-        iconMainFriendGuardAndroid,
-        iconMainHelp,
-        iconMainHelpAndroid,
-        iconMainMapClock,
+        iconMainFriend,
+        iconMainLeftSlipArrow,
+        iconMainLocation,
         iconMainMine,
-        iconMainMineAndroid,
         iconMainNews,
-        iconMainNewsAndroid,
+        iconMainRefresh,
         iconMainRefreshFriendLocation,
         iconMainRefreshMineLocation,
         iconMainTrackArrow,
+        iconMainTrackLocation,
         iconMemberActivityClose,
         iconMemberActivityCountdown,
         iconMemberActivityCoupon,
@@ -1007,6 +991,7 @@ class $AssetsImagesGen {
         imgDialogLocationAlwaysTip1,
         imgDialogLocationAlwaysTip2,
         imgDialogLocationAlwaysTip3,
+        imgMainCaringReport,
         imgMemberActivityBanner1,
         imgMemberActivityBanner2,
         imgMemberActivityBanner3,

+ 7 - 0
lib/resource/string.gen.dart

@@ -5,6 +5,8 @@ class StringName {
   static String get appName => 'app_name'.tr; // 手机实时定位
   static String get appNameIos => 'app_name_ios'.tr; // 手机实时定位
   static String get mainTabHome => 'main_tab_home'.tr; // 首页
+  static String get mainTabFriend => 'main_tab_friend'.tr; // 好友
+  static String get mainTabNews => 'main_tab_news'.tr; // 消息
   static String get mainTabCamera => 'main_tab_camera'.tr; // 扫一扫
   static String get mainTabMine => 'main_tab_mine'.tr; // 我的
   static String get loadingMore => 'loading_more'.tr; // 加载更多
@@ -399,6 +401,8 @@ class StringName {
       'select_address_please'.tr; // 请在列表下方选择一个详细地址
   static String get dialogAddFriendNextTime =>
       'dialog_add_friend_next_time'.tr; // 下次再说
+  static String get mainLeftSlipSwitch =>
+      'main_left_slip_switch'.tr; // 左\n滑\n切\n换
 }
 class StringMultiSource {
   StringMultiSource._();
@@ -407,6 +411,8 @@ class StringMultiSource {
       'app_name': '手机实时定位',
       'app_name_ios': '手机实时定位',
       'main_tab_home': '首页',
+      'main_tab_friend': '好友',
+      'main_tab_news': '消息',
       'main_tab_camera': '扫一扫',
       'main_tab_mine': '我的',
       'loading_more': '加载更多',
@@ -778,6 +784,7 @@ class StringMultiSource {
       'current_location': '[当前位置]',
       'select_address_please': '请在列表下方选择一个详细地址',
       'dialog_add_friend_next_time': '下次再说',
+      'main_left_slip_switch': '左\n滑\n切\n换',
     },
   };
 }

+ 10 - 6
lib/widget/activity_countdown_txt_view.dart

@@ -77,12 +77,16 @@ class _ActivityCountdownTxtViewState extends State<ActivityCountdownTextView> {
       alignment: Alignment.center,
       padding: widget.contentPadding,
       decoration: widget.timeBgBoxDecoration,
-      child: Text(
-        text,
-        maxLines: 1,
-        style: widget.textStyle ??
-            const TextStyle(
-                fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white),
+      child: Center(
+        child: Text(
+          text,
+          maxLines: 1,
+          style: widget.textStyle ??
+              const TextStyle(
+                  fontSize: 20,
+                  fontWeight: FontWeight.bold,
+                  color: Colors.white),
+        ),
       ),
     );
   }

+ 0 - 110
lib/widget/activity_countdown_view.dart

@@ -1,110 +0,0 @@
-import 'dart:async';
-import 'package:flutter/material.dart';
-
-class ActivityCountdownView extends StatefulWidget {
-  final Duration duration;
-  final TextStyle? textStyle;
-  final BoxDecoration? timeBgBoxDecoration;
-  final double? timeItemWidth;
-  final double? timeItemHeight;
-  final BoxFit bgFit;
-  final EdgeInsetsGeometry contentPadding;
-  final Widget? separator;
-  final VoidCallback? onFinish;
-
-  const ActivityCountdownView({
-    super.key,
-    required this.duration,
-    this.timeBgBoxDecoration,
-    this.textStyle,
-    this.timeItemWidth,
-    this.timeItemHeight,
-    this.bgFit = BoxFit.contain,
-    this.contentPadding = const EdgeInsets.all(4),
-    this.separator,
-    this.onFinish,
-  });
-
-  @override
-  State<ActivityCountdownView> createState() => _ActivityCountdownViewState();
-}
-
-class _ActivityCountdownViewState extends State<ActivityCountdownView> {
-  late Duration _remaining;
-  Timer? _timer;
-
-  @override
-  void initState() {
-    super.initState();
-    _remaining = widget.duration;
-    _startTimer();
-  }
-
-  void _startTimer() {
-    _timer = Timer.periodic(const Duration(seconds: 1), (_) {
-      if (_remaining.inSeconds <= 1) {
-        _timer?.cancel();
-        widget.onFinish?.call();
-        setState(() {
-          _remaining = const Duration(seconds: 0);
-        });
-      } else {
-        setState(() {
-          _remaining -= const Duration(seconds: 1);
-        });
-      }
-    });
-  }
-
-  String _twoDigits(int n) => n.toString().padLeft(2, '0');
-
-  @override
-  Widget build(BuildContext context) {
-    final hours = _twoDigits(_remaining.inHours);
-    final minutes = _twoDigits(_remaining.inMinutes.remainder(60));
-    final seconds = _twoDigits(_remaining.inSeconds.remainder(60));
-
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      children: [
-        _buildTimeBox(hours),
-        _buildSeparator(),
-        _buildTimeBox(minutes),
-        _buildSeparator(),
-        _buildTimeBox(seconds),
-      ],
-    );
-  }
-
-  /// 自定义时间数字块,2位合并显示
-  Widget _buildTimeBox(String text) {
-    return Container(
-      width: widget.timeItemWidth,
-      height: widget.timeItemHeight,
-      alignment: Alignment.center,
-      padding: widget.contentPadding,
-      decoration: widget.timeBgBoxDecoration,
-      child: Text(
-        text,
-        maxLines: 1,
-        style: widget.textStyle ??
-            const TextStyle(
-                fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white),
-      ),
-    );
-  }
-
-  /// 自定义分隔符(冒号),如果未设置就给默认间距
-  Widget _buildSeparator() {
-    return widget.separator ??
-        const SizedBox(
-          width: 4,
-        );
-  }
-
-  @override
-  void dispose() {
-    _timer?.cancel();
-    super.dispose();
-  }
-}

+ 36 - 45
lib/widget/marquee_text.dart

@@ -1,65 +1,56 @@
-import 'package:flutter/material.dart';
+import 'package:flutter/cupertino.dart';
 import 'package:marquee/marquee.dart';
 
-typedef MarqueeBuilder = Marquee Function(
-    BuildContext context, String text, TextStyle textStyle);
-typedef TextBuilder = Text Function(
-    BuildContext context, String text, TextStyle textStyle);
-
 class MarqueeText extends StatelessWidget {
   final String text;
   final TextStyle textStyle;
-  final double containerWidth;
-  final TextBuilder textBuilder;
-  final MarqueeBuilder marqueeBuilder;
+  final double velocity;
+  final double blankSpace;
 
   const MarqueeText({
     super.key,
-    required this.marqueeBuilder,
-    required this.textBuilder,
     required this.text,
     required this.textStyle,
-    required this.containerWidth,
+    this.velocity = 18.0,
+    this.blankSpace = 20.0,
   });
 
-  static MarqueeText marquee(
-      {required String text,
-      required TextStyle textStyle,
-      required double containerWidth,
-      double velocity = 18.0,
-      double blankSpace = 20}) {
-    return MarqueeText(
-      text: text,
-      textStyle: textStyle,
-      containerWidth: containerWidth,
-      textBuilder: (context, text, textStyle) {
-        return Text(text, style: textStyle);
-      },
-      marqueeBuilder: (context, text, textStyle) {
-        return Marquee(
-            text: text,
-            style: textStyle,
-            blankSpace: blankSpace,
-            pauseAfterRound: Duration(seconds: 2),
-            velocity: velocity);
-      },
-    );
-  }
-
-  Size calculateTextSize(String text, TextStyle style) {
+  Size _calculateTextSize(String text, TextStyle style) {
     final TextPainter textPainter = TextPainter(
-        text: TextSpan(text: text, style: style),
-        maxLines: 1,
-        textDirection: TextDirection.ltr)
-      ..layout(minWidth: 0, maxWidth: double.infinity);
+      text: TextSpan(text: text, style: style),
+      maxLines: 1,
+      textDirection: TextDirection.ltr,
+    )..layout(minWidth: 0, maxWidth: double.infinity);
     return textPainter.size;
   }
 
   @override
   Widget build(BuildContext context) {
-    final textWidth = calculateTextSize(text, textStyle).width;
-    return textWidth < containerWidth
-        ? textBuilder(context, text, textStyle)
-        : marqueeBuilder(context, text, textStyle);
+    return LayoutBuilder(
+      builder: (context, constraints) {
+        final maxWidth = constraints.maxWidth; // 👈 父级能给的剩余宽度
+        final textWidth = _calculateTextSize(text, textStyle).width;
+
+        if (textWidth <= maxWidth) {
+          return Text(
+            text,
+            style: textStyle,
+            maxLines: 1,
+            overflow: TextOverflow.ellipsis,
+          );
+        } else {
+          return SizedBox(
+            width: maxWidth,
+            child: Marquee(
+              text: text,
+              style: textStyle,
+              blankSpace: blankSpace,
+              pauseAfterRound: const Duration(seconds: 2),
+              velocity: velocity,
+            ),
+          );
+        }
+      },
+    );
   }
 }

+ 1 - 1
plugins/map/lib/src/core/map_base_controller.dart

@@ -17,7 +17,7 @@ abstract class MapController
 
   // 创建默认实现的方法 或 通过MapControllerFactory 来创建
   factory MapController.create() {
-    return MapControllerImpl();
+    return MapControllerFactory.createDefault();
   }
 }
 

+ 10 - 2
plugins/map/lib/src/entity/marker.dart

@@ -44,15 +44,23 @@ class Marker implements Codable {
   }
 
   factory Marker.fromJson(Map<String, dynamic> map) {
+    bool parseBool(dynamic value) {
+      if (value == null) return false;
+      if (value is bool) return value;
+      if (value is int) return value != 0;
+      if (value is String) return value.toLowerCase() == 'true';
+      return false;
+    }
+
     return Marker(
       id: map['id'],
       markerName: map['markerName'],
       longitude: map['longitude'],
       latitude: map['latitude'],
       markerType: MarkerType.fromValue(map['markerType'] as int),
-      isSelected: map['isSelected'],
+      isSelected: parseBool(map['isSelected']),
       customAvatarUrl: map['customAvatarUrl'] as String?,
-      tags: map['tags'] ? map['tags'] : null,
+      tags: map['tags'],
     );
   }
 }