Ver código fonte

update community module

gaol 1 semana atrás
pai
commit
4d4dd50b48

+ 0 - 126
packages/cpt_community/lib/components/custom_tabs.dart

@@ -1,126 +0,0 @@
-import 'package:cpt_community/components/custom_tabs_state.dart';
-import 'package:cpt_community/components/custom_tabs_state.dart';
-import 'package:cpt_community/modules/newsfeed/newsfeed_vm.dart';
-import 'package:cs_resources/theme/app_colors_theme.dart';
-import 'package:flutter/material.dart';
-import 'package:auto_route/auto_route.dart';
-import 'package:flutter_hooks/flutter_hooks.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:router/ext/auto_router_extensions.dart';
-import 'package:shared/utils/color_utils.dart';
-import 'package:shared/utils/log_utils.dart';
-import 'package:widgets/my_load_image.dart';
-import 'package:widgets/ext/ex_widget.dart';
-import 'package:widgets/my_text_view.dart';
-import 'package:widgets/my_appbar.dart';
-
-import '../modules/community/community_vm.dart';
-import '../modules/garagesale/garagesale_vm.dart';
-import 'custom_tabs_state.dart';
-import 'custom_tabs_vm.dart';
-
-class CustomTabs extends HookConsumerWidget {
-  List tabsList;
-  Widget? Function(BuildContext)? tabItemBuilder;
-  VoidCallback? onClickAction;
-  CustomTabs({
-    Key? key,
-    required this.tabsList,
-    this.onClickAction,
-    this.tabItemBuilder
-  }) : super(key: key);
-
-  Widget _buildTabItem(BuildContext context, WidgetRef ref, vm, item, index) {
-    // 监听 activeIndex 的变化
-    final activeTabIndex = ref.watch(customTabsVmProvider.select((state) => state.activeTabIndex));
-    // final activeTabItemIndex = item['active'];
-
-
-    return Container(
-        width: MediaQuery.of(context).size.width / vm.state.tabsList.length - 30,
-        height: 43,
-        padding: const EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
-        decoration: index==activeTabIndex? BoxDecoration(
-          color: index==activeTabIndex? context.appColors.btnBgDefault: ColorUtils.string2Color("#F2F3F6"),
-          borderRadius: BorderRadius.circular(20),
-          boxShadow: [
-            BoxShadow(
-              color: Colors.grey.withOpacity(0.5),
-              spreadRadius: 1,
-              blurRadius: 5,
-              offset: const Offset(0, 2), // changes position of shadow
-            ),
-          ],
-        ): null,
-        child: Row(
-          children: [
-            Expanded(
-              child: Container(
-                alignment: Alignment.center,
-                child: MyTextView(
-                  item['title'],
-                  fontSize: 16,
-                  textAlign: TextAlign.center,
-                  isFontMedium: true,
-                  textColor: index == activeTabIndex ? Colors.white :ColorUtils.string2Color("#000000"),
-                ),
-              ),
-            ),
-          ],
-        ),
-    ).onTap((){
-      vm.handlerClickTab(index, item);
-    });
-  }
-
-  List<Widget> _buildTabs(BuildContext context, WidgetRef ref, vm, tablist){
-
-    int currentUseTag = ref.watch(customTabsVmProvider.select((state) => state.useTag!));
-
-    ref.listen(customTabsVmProvider.select((state) => state.useTag), (previous, next) {
-      // 设置当前的 tabsList
-      if(next == 1){
-        // Garage Sale
-        List tabsList = ref.read(newsfeedVmProvider).tabsList;
-      }else if(next == 0){
-        List tabsList = ref.read(garagesaleVmProvider).tabsList;
-      }
-
-    });
-    int tabsLength = tabsList.length;
-
-    print("000328942424----${tabsList}");
-
-    return List.generate(tabsLength, (index) {
-      return _buildTabItem(context, ref, vm, tabsList[index], index);
-    });
-  }
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final vm = ref.watch(customTabsVmProvider.notifier);
-    // 使用useEffect钩子
-    useEffect(() {
-      print('副作用函数执行');
-      // 这里是副作用逻辑
-      vm.initPropData(tabsList, tabItemBuilder, onClickAction);
-      // 返回清理函数
-      return () {
-        print('清理函数执行');
-      };
-    }, []); // 空依赖列表意味着这个副作用只在组件挂载时执行一次
-
-    return SingleChildScrollView(
-      scrollDirection: Axis.horizontal,
-      physics: const BouncingScrollPhysics(),
-      clipBehavior: Clip.none,
-      child: Row(
-        mainAxisSize: MainAxisSize.max,
-        mainAxisAlignment: MainAxisAlignment.center,
-        children: _buildTabs(context, ref, vm, tabsList),
-      ).constrained(
-        maxWidth:  MediaQuery.of(context).size.width
-      ),
-    );
-  }
-}

+ 0 - 53
packages/cpt_community/lib/components/custom_tabs_state.dart

@@ -1,53 +0,0 @@
-import 'package:flutter/cupertino.dart';
-
-class CustomTabsState {
-  int? useTag = 0;
-  int? activeTabIndex = 0;
-  List? tabsList;
-  Widget? Function(BuildContext)? tabItemBuilder;
-  VoidCallback? onClickAction;
-
-  CustomTabsState({
-    this.useTag,
-    this.activeTabIndex,
-    this.tabsList,
-    this.tabItemBuilder,
-    this.onClickAction,
-  });
-
-  CustomTabsState copyWith({
-    int? useTag,
-    int? activeTabIndex,
-    List? tabsList,
-    Widget? Function(BuildContext)? tabItemBuilder,
-    VoidCallback? onClickAction,
-  }) {
-    return CustomTabsState(
-      useTag: useTag ?? this.useTag,
-      activeTabIndex: activeTabIndex ?? this.activeTabIndex,
-      tabsList: tabsList ?? this.tabsList,
-      tabItemBuilder: tabItemBuilder ?? this.tabItemBuilder,
-      onClickAction: onClickAction ?? this.onClickAction,
-    );
-  }
-
-  Map<String, dynamic> toMap() {
-    return {
-      'useTag': this.useTag,
-      'activeTabIndex': this.activeTabIndex,
-      'tabsList': this.tabsList,
-      'tabItemBuilder': this.tabItemBuilder,
-      'onClickAction': this.onClickAction,
-    };
-  }
-
-  factory CustomTabsState.fromMap(Map<String, dynamic> map) {
-    return CustomTabsState(
-      useTag: map['useTag'] as int,
-      activeTabIndex: map['activeTabIndex'] as int,
-      tabsList: map['tabsList'] as List,
-      tabItemBuilder: map['tabItemBuilder'] as Widget? Function(BuildContext),
-      onClickAction: map['onClickAction'] as VoidCallback,
-    );
-  }
-}

+ 0 - 117
packages/cpt_community/lib/components/custom_tabs_vm.dart

@@ -1,117 +0,0 @@
-
-import 'package:cpt_community/components/custom_tabs_state.dart';
-import 'package:cpt_community/modules/community/community_vm.dart';
-import 'package:cpt_community/modules/garagesale/garagesale_vm.dart';
-import 'package:cpt_community/modules/newsfeed/newsfeed_vm.dart';
-import 'package:cs_resources/generated/assets.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:plugin_platform/engine/toast/toast_engine.dart';
-import 'package:riverpod_annotation/riverpod_annotation.dart';
-import 'package:shared/utils/log_utils.dart';
-
-part 'custom_tabs_vm.g.dart';
-
-@riverpod
-class CustomTabsVm extends _$CustomTabsVm {
-
-  CustomTabsState initState(int? useTag, List? tabsList, tabItemBuilder, onClickAction) {
-    CustomTabsState state = CustomTabsState(
-        useTag: useTag??0,
-        activeTabIndex: 0,
-        tabsList: tabsList ?? [],
-        tabItemBuilder:tabItemBuilder,
-        onClickAction: onClickAction
-    );
-
-    return state;
-  }
-
-  @override
-  CustomTabsState build(){
-    print("5656566---${ref.read(communityVmProvider).useTag}");
-    // 当前的 useTag
-    // setUseTag(ref.read(communityVmProvider).useTag as int);
-
-    // 监听 UserVM 的状态变化
-    ref.listen(communityVmProvider.select((community) => community.useTag), (previous, next) {
-      print('community useTag changed from $previous to $next');
-      // 设置当前的 tabsList
-      if(next == 1){
-        // Garage Sale
-        setUseTag(1);
-      }else if(next == 0){
-        setUseTag(0);
-      }
-
-    });
-
-    CustomTabsState state = initState(0,[], null, null);
-    return state;
-  }
-
-  // 设置当前的 useTag
-  void setUseTag(int useTag) {
-    CustomTabsState newState = state.copyWith(useTag: useTag);
-    state = newState;
-  }
-
-  // 设置当前的tabsList
-  void setTabsList() {
-    List currentTabsList =  [];
-    if(state.useTag == 0){
-      // 找到 newsfeed 中的 tabsList
-      currentTabsList = ref.read(newsfeedVmProvider).tabsList;
-    }else if(state.useTag == 1){
-      currentTabsList = ref.read(garagesaleVmProvider).tabsList;
-    }
-
-    CustomTabsState newState = state.copyWith(tabsList: currentTabsList);
-    state = newState;
-  }
-
-  // 将组件构造器中的参数保存到state中
-  Future<void> initPropData(tabsList,tabItemBuilder, onClickAction) async {
-    // 获取 community 中的 useTag
-    // state = state.copyWith(useTag: ref.watch(communityVmProvider).useTag);
-    CustomTabsState newState = state.copyWith(
-        tabsList: tabsList,
-        tabItemBuilder: tabItemBuilder,
-        onClickAction: onClickAction
-    );
-    state = newState;
-  }
-
-
-  // 点击tab
-  void handlerClickTab(int index, item){
-    setTabsList();
-
-    // List newState = state.tabsList!.asMap().entries.map((entry) {
-    //   Map<String, dynamic> obj = entry.value;
-    //   int idx = entry.key;
-    //
-    //   if (obj['title'] == item['title'] && index == idx) {
-    //     return {
-    //       ...obj,
-    //       'active': true,
-    //     };
-    //   } else {
-    //     return {
-    //       ...obj,
-    //       'active': false,
-    //     };
-    //   }
-    // }).toList();
-    //
-    // // if(state.useTag)
-    // // 修改当前item 的active
-    // state = state.copyWith(tabsList: newState);
-    state = state.copyWith(activeTabIndex: index);
-
-    print("切换后新的 sate, ${state.tabsList}");
-
-    // ref.invalidate(customTabsVmProvider);
-  }
-
-}

+ 0 - 25
packages/cpt_community/lib/components/custom_tabs_vm.g.dart

@@ -1,25 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'custom_tabs_vm.dart';
-
-// **************************************************************************
-// RiverpodGenerator
-// **************************************************************************
-
-String _$customTabsVmHash() => r'e2bd34f81601b8309c31bbcdb1183d81e83b66d6';
-
-/// See also [CustomTabsVm].
-@ProviderFor(CustomTabsVm)
-final customTabsVmProvider =
-    AutoDisposeNotifierProvider<CustomTabsVm, CustomTabsState>.internal(
-  CustomTabsVm.new,
-  name: r'customTabsVmProvider',
-  debugGetCreateSourceHash:
-      const bool.fromEnvironment('dart.vm.product') ? null : _$customTabsVmHash,
-  dependencies: null,
-  allTransitiveDependencies: null,
-);
-
-typedef _$CustomTabsVm = AutoDisposeNotifier<CustomTabsState>;
-// ignore_for_file: type=lint
-// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 48 - 18
packages/cpt_community/lib/modules/community/community_page.dart

@@ -1,6 +1,7 @@
 
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter/rendering.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
@@ -54,7 +55,7 @@ class CommunityPage extends HookConsumerWidget {
                         decoration: BoxDecoration(
                           // color: currentTabIdx == index ? ColorUtils.string2Color('#E6F2FF') : Colors.white,
                           shape: BoxShape.circle, // 设置为圆形
-                          boxShadow: tabsRouter.activeIndex == index ? [
+                          boxShadow: currentTabIdx == index ? [
                             BoxShadow(
                               color: context.appColors.tabLightBlueShadow, // 设置阴影颜色
                               blurRadius: 5, // 设置模糊半径
@@ -104,25 +105,54 @@ class CommunityPage extends HookConsumerWidget {
               backgroundColor: context.appColors.whiteBG,
             ),
             backgroundColor: context.appColors.backgroundDefault,
-          body: AutoTabsRouter.pageView(
-            routes: const [
-              NewsfeedPageRoute(),
-              GaragesalePageRoute(),
-            ],
-            builder: (context, child, pageController) {
-              print("pageView child: $child,  $pageController");
-              final tabsRouter = AutoTabsRouter.of(context);
-              // 设置当前的 useTag 0 newsFeed 1 garageSale
-              vm.setCurrentUseTag(tabsRouter.activeIndex);
-              return Column(
-                children: [
-                  _buildTopSection(context, ref, vm, tabsRouter),
-                  Expanded(
-                    child: child,
+          body: NestedScrollView(
+              headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled){
+                return <Widget>[
+                  SliverToBoxAdapter(
+                    child: Container(
+                      child: const SizedBox.shrink(),
+                    )
                   ),
+                  SliverToBoxAdapter(
+                    child: Consumer(
+                      builder: (context, ref, _) {
+                        final tabsRouter = ref.watch(communityVmProvider).tabsRouter;
+                        final vm = ref.read(communityVmProvider.notifier);
+                        Log.d("community_page---buildTopSection ---${tabsRouter}");
+                        Log.d("community_page---buildTopSection ---${vm.state.curIdx}");
+
+                        // return _buildTopSection(context, ref, vm, tabsRouter);
+                        if(tabsRouter != null){
+                          return _buildTopSection(context, ref, vm, tabsRouter);
+                        }else {
+                          return const SizedBox.shrink();
+                        }
+                      },
+                    ),
+                  ),
+                ];
+              },
+              body: AutoTabsRouter.pageView(
+                routes: const [
+                  NewsfeedPageRoute(),
+                  GaragesalePageRoute(),
                 ],
-              );
-            },
+                builder: (context, child, pageController) {
+                  final tabsRouter = AutoTabsRouter.of(context);
+                  // 设置当前的 useTag 0 newsFeed 1 garageSale
+                  vm.setCurrentUseTag(tabsRouter.activeIndex);
+                  // 将tabsRouter 放入 CommunityVmProvider 中
+                  vm.setTabsRouterAndPageController(tabsRouter, pageController);
+                  return Column(
+                    children: [
+                      // _buildTopSection(context, ref, vm, tabsRouter),
+                      Expanded(
+                        child: child,
+                      ),
+                    ],
+                  );
+                },
+              ),
           ),
         );
     }

+ 10 - 0
packages/cpt_community/lib/modules/community/community_state.dart

@@ -8,10 +8,16 @@ class CommunityVmState {
   List<Map<String, dynamic>>? topSectionsData;
   int? curIdx;
 
+  dynamic? tabsRouter;
+  dynamic? pageController;
+
+
   CommunityVmState({
     this.useTag = 0,
     List<Map<String, dynamic>>? topSectionsData,
     this.curIdx = 0,
+    this.tabsRouter,
+    this.pageController,
   }) : topSectionsData = topSectionsData?? [
     {
       "title": "News Feed",
@@ -31,11 +37,15 @@ class CommunityVmState {
     int? useTag,
     List<Map<String, dynamic>>? topSectionsData,
     int? curIdx = 0,
+    dynamic? tabsRouter,
+    dynamic? pageController,
   }) {
     return CommunityVmState(
       useTag: useTag ?? this.useTag,
       topSectionsData: topSectionsData ?? this.topSectionsData,
       curIdx: curIdx ?? 0,
+      tabsRouter: tabsRouter ?? this.tabsRouter,
+      pageController: pageController ?? this.pageController,
     );
   }
 }

+ 8 - 1
packages/cpt_community/lib/modules/community/community_vm.dart

@@ -28,8 +28,15 @@ class CommunityVm extends _$CommunityVm {
     return state;
   }
 
+   // 设置当前的 tabsRouter 和 pageController
+  Future setTabsRouterAndPageController(dynamic tabsRouter, dynamic pageController) async{
+    Log.d("setTabsRouterAndPageController---: $tabsRouter");
+    state = await state.copyWith(tabsRouter: tabsRouter, pageController: pageController,curIdx: tabsRouter.activeIndex);
+  }
+
+
    Future setCurrentUseTag(int useTag) async {
-    state = await state.copyWith(useTag: useTag);
+    state = await state.copyWith(useTag: useTag, curIdx: useTag);
     Log.d("useTag----: $useTag");
   }
 

+ 1 - 1
packages/cpt_community/lib/modules/community/community_vm.g.dart

@@ -6,7 +6,7 @@ part of 'community_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$communityVmHash() => r'afd60e421d8c9dadc0197b7944dc915e5349d9b1';
+String _$communityVmHash() => r'15dfd5c8d9c3d01bab9fc789c21ebe61b292c6f3';
 
 /// See also [CommunityVm].
 @ProviderFor(CommunityVm)

+ 62 - 18
packages/cpt_community/lib/modules/garagesale/garagesale_page.dart

@@ -1,10 +1,10 @@
 
-import 'package:cpt_community/components/custom_tabs.dart';
 import 'package:cpt_community/components/newsfeed_card_content.dart';
 import 'package:cpt_community/components/newsfeed_card_footer.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter/rendering.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/color_utils.dart';
@@ -16,8 +16,12 @@ import 'package:widgets/widget_export.dart';
 
 import '../../components/newfeed_card_header.dart';
 import '../../router/page/community_page_router.dart';
+import '../community/community_vm.dart';
+import 'garagesale_tabs.dart';
+
 import 'garagesale_vm.dart';
 
+
 @RoutePage()
 class GaragesalePage extends HookConsumerWidget {
   const GaragesalePage({Key? key}) : super(key: key);
@@ -32,13 +36,11 @@ class GaragesalePage extends HookConsumerWidget {
   }
 
   Widget _buildTabsSection(BuildContext context, WidgetRef ref, vm){
-    print("222222222222222222${vm.state.tabsList}");
     return Container(
       width: double.infinity,
       padding: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 14),
-      child: CustomTabs(
-          key: UniqueKey(),
-          tabsList: vm.state.tabsList,
+      child: GaragesaleTabs(
+        tabsList: vm.state.tabsList,
       ),
     );
   }
@@ -158,19 +160,61 @@ class GaragesalePage extends HookConsumerWidget {
 
           _buildPostSection(context, ref, vm),
 
-          Expanded(
-            child: EasyRefresh(
-              // 上拉加载
-              onLoad: () async{
-                Log.d("----onLoad");
-                vm.onLoadData();
-              },
-              // 下拉刷新
-              onRefresh: () async{
-                Log.d("----onRefresh");
-                vm.refreshListData();
-              },
-              child: _buildNesFeedList(context, ref, vm),
+          NotificationListener<ScrollNotification>(
+            onNotification: (ScrollNotification notification) {
+              // 检查当前页面是否是可见的
+              bool isDownOrUp = notification.metrics.axis == Axis.vertical;
+              if (notification is UserScrollNotification) {
+                // 检查滚动方向
+                switch (notification.direction) {
+                  case ScrollDirection.forward:
+                    print('Scrolling down');
+                    break;
+                  case ScrollDirection.reverse:
+                    print('Scrolling up');
+                    break;
+                  case ScrollDirection.idle:
+                    print('Scrolling stopped');
+                    break;
+                }
+              } else if (notification is ScrollUpdateNotification) {
+                // 检查滚动位置变化
+                double currentScrollPosition = notification.metrics.pixels;
+                double maxScrollExtent = notification.metrics.maxScrollExtent;
+
+                // 判断是否满足某个条件
+                if (currentScrollPosition > 0 && currentScrollPosition < maxScrollExtent) {
+                  print('Current scroll position: $currentScrollPosition');
+                  // 在这里添加你的条件判断逻辑
+                }
+
+                // 只有当上下滚动时才拦截通知
+                if (notification.metrics.axis == Axis.vertical) {
+                  final tabsRouter = ref.watch(communityVmProvider).tabsRouter;
+                  final curUseTag = ref.watch(communityVmProvider).useTag;
+
+                  if(curUseTag != 1 ){
+                    // 非当前 页面都阻止滚动
+                    return true; // 返回 true 表示已处理通知
+                  }
+                }
+              }
+              return false; // 返回 false 表示不拦截通知
+            },
+            child: Expanded(
+              child: EasyRefresh(
+                // 上拉加载
+                onLoad: () async{
+                  Log.d("----onLoad");
+                  vm.onLoadData();
+                },
+                // 下拉刷新
+                onRefresh: () async{
+                  Log.d("----onRefresh");
+                  vm.refreshListData();
+                },
+                child: _buildNesFeedList(context, ref, vm),
+              ),
             ),
           )
         ],

+ 110 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_tabs.dart

@@ -0,0 +1,110 @@
+import 'package:cpt_community/modules/newsfeed/newsfeed_vm.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/my_appbar.dart';
+
+import '../community/community_vm.dart';
+import '../garagesale/garagesale_vm.dart';
+
+class GaragesaleTabs extends HookConsumerWidget {
+  List tabsList;
+  Widget? Function(BuildContext)? tabItemBuilder;
+  VoidCallback? onClickAction;
+  GaragesaleTabs({
+    Key? key,
+    required this.tabsList,
+    this.onClickAction,
+    this.tabItemBuilder
+  }) : super(key: key);
+
+  Widget _buildTabItem(BuildContext context, WidgetRef ref, vm, item, index) {
+    // 监听 activeIndex 的变化
+    final activeIndex = ref.watch(garagesaleVmProvider.select((state) => state.activeIndex));
+
+
+    return Container(
+      width: MediaQuery.of(context).size.width / vm.state.tabsList.length - 30,
+      height: 43,
+      padding: const EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
+      decoration: index==activeIndex? BoxDecoration(
+        color: index==activeIndex? context.appColors.btnBgDefault: ColorUtils.string2Color("#F2F3F6"),
+        borderRadius: BorderRadius.circular(20),
+        boxShadow: [
+          BoxShadow(
+            color: Colors.grey.withOpacity(0.5),
+            spreadRadius: 1,
+            blurRadius: 5,
+            offset: const Offset(0, 2), // changes position of shadow
+          ),
+        ],
+      ): null,
+      child: Row(
+        children: [
+          Expanded(
+            child: Container(
+              alignment: Alignment.center,
+              child: MyTextView(
+                item['title'],
+                fontSize: 16,
+                textAlign: TextAlign.center,
+                isFontMedium: true,
+                textColor: index == activeIndex ? Colors.white :ColorUtils.string2Color("#000000"),
+              ),
+            ),
+          ),
+        ],
+      ),
+    ).onTap((){
+      vm.handlerClickTab(index, item);
+    });
+  }
+
+  List<Widget> _buildTabs(BuildContext context, WidgetRef ref, vm){
+
+    int currentUseTag = ref.watch(garagesaleVmProvider.select((state) => state.useTag!));
+
+    List tabsList = ref.read(garagesaleVmProvider).tabsList;
+
+    int tabsLength = tabsList.length;
+
+    return List.generate(tabsLength, (index) {
+      return _buildTabItem(context, ref, vm, tabsList[index], index);
+    });
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final vm = ref.read(garagesaleVmProvider.notifier);
+    // 使用useEffect钩子
+    useEffect(() {
+      print('副作用函数执行');
+      // 这里是副作用逻辑
+      // 返回清理函数
+      return () {
+        print('清理函数执行');
+      };
+    }, []); // 空依赖列表意味着这个副作用只在组件挂载时执行一次
+
+    return SingleChildScrollView(
+      scrollDirection: Axis.horizontal,
+      physics: const BouncingScrollPhysics(),
+      clipBehavior: Clip.none,
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: _buildTabs(context, ref, vm),
+      ).constrained(
+          maxWidth:  MediaQuery.of(context).size.width
+      ),
+    );
+  }
+}

+ 10 - 2
packages/cpt_community/lib/modules/garagesale/garagesale_vm.dart

@@ -75,7 +75,7 @@ class GaragesaleVm extends _$GaragesaleVm {
 
   // 上拉加载
   Future onLoadData() async {
-    Log.d("----property_news_vm-----initListData");
+    Log.d("----garagesale_vm-----initListData");
     // await Future.delayed(const Duration(seconds: 2));
     // if(state.list.length >= state.filterCount){
     //   return;
@@ -115,7 +115,7 @@ class GaragesaleVm extends _$GaragesaleVm {
 
   // 下拉刷新
   Future refreshListData() async {
-    Log.d("----property_news_vm-----refreshListData ");
+    Log.d("----garagesale_vm-----refreshListData ");
 
     // await Future.delayed(const Duration(seconds: 2));
 
@@ -134,4 +134,12 @@ class GaragesaleVm extends _$GaragesaleVm {
 
     AutoRouter.of(context).pushNamed(RouterPath.garageSalePost);
   }
+
+  // 点击tab
+  void handlerClickTab(int index, item){
+    state = state.copyWith(activeIndex: index);
+    print("切换后新的 sate, ${state.tabsList}");
+
+    // ref.invalidate(customTabsVmProvider);
+  }
 }

+ 1 - 1
packages/cpt_community/lib/modules/garagesale/garagesale_vm.g.dart

@@ -6,7 +6,7 @@ part of 'garagesale_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$garagesaleVmHash() => r'1126da2a80e07f51187fa144b966295b572dea32';
+String _$garagesaleVmHash() => r'd531a4a4393b7310a34957d2636d8be9f4a3d697';
 
 /// See also [GaragesaleVm].
 @ProviderFor(GaragesaleVm)

+ 48 - 6
packages/cpt_community/lib/modules/newsfeed/newsfeed_page.dart

@@ -1,10 +1,10 @@
 
-import 'package:cpt_community/components/custom_tabs.dart';
 import 'package:cpt_community/components/newsfeed_card_content.dart';
 import 'package:cpt_community/components/newsfeed_card_footer.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter/rendering.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/color_utils.dart';
@@ -16,6 +16,8 @@ import 'package:widgets/widget_export.dart';
 
 import '../../components/newfeed_card_header.dart';
 import '../../router/page/community_page_router.dart';
+import '../community/community_vm.dart';
+import 'newsfeed_tabs.dart';
 import 'newsfeed_vm.dart';
 
 @RoutePage()
@@ -35,9 +37,8 @@ class NewsfeedPage extends HookConsumerWidget {
     return Container(
       width: double.infinity,
       padding: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 14),
-      child: CustomTabs(
-          key: UniqueKey(),
-          tabsList: vm.state.tabsList,
+      child: NewsfeedTabs(
+        tabsList: vm.state.tabsList,
       ),
     );
   }
@@ -174,8 +175,49 @@ class NewsfeedPage extends HookConsumerWidget {
             //     child: _buildNesFeedList(context, ref, vm),
             //   ),
             // )
-            Expanded(
-              child: _buildNesFeedList(context, ref, vm),
+            NotificationListener <ScrollNotification>(
+              onNotification: (ScrollNotification notification) {
+                // 检查当前页面是否是可见的
+                bool isDownOrUp = notification.metrics.axis == Axis.vertical;
+                if (notification is UserScrollNotification) {
+                  // 检查滚动方向
+                  switch (notification.direction) {
+                    case ScrollDirection.forward:
+                      print('Scrolling down');
+                      break;
+                    case ScrollDirection.reverse:
+                      print('Scrolling up');
+                      break;
+                    case ScrollDirection.idle:
+                      print('Scrolling stopped');
+                      break;
+                  }
+                } else if (notification is ScrollUpdateNotification) {
+                  // 检查滚动位置变化
+                  double currentScrollPosition = notification.metrics.pixels;
+                  double maxScrollExtent = notification.metrics.maxScrollExtent;
+
+                  // 判断是否满足某个条件
+                  if (currentScrollPosition > 0 && currentScrollPosition < maxScrollExtent) {
+                    print('Current scroll position: $currentScrollPosition');
+                    // 在这里添加你的条件判断逻辑
+                  }
+
+                  // 只有当上下滚动时才拦截通知
+                  if (notification.metrics.axis == Axis.vertical) {
+                    final tabsRouter = ref.watch(communityVmProvider).tabsRouter;
+                    final curUseTag = ref.watch(communityVmProvider).useTag;
+                    if(curUseTag != 0 ){
+                      // 非当前 页面都阻止滚动
+                      return true; // 返回 true 表示已处理通知
+                    }
+                  }
+                }
+                return false; // 返回 false 表示不拦截通知
+              },
+              child: Expanded(
+                child: _buildNesFeedList(context, ref, vm),
+              ),
             )
           ],
       ),

+ 3 - 3
packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_vm.g.dart

@@ -6,12 +6,12 @@ part of 'newsfeed_post_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$newsfeedPostVmHash() => r'24057c043ffdf4ff3718e624cd94efb609dfd662';
+String _$newsfeedPostVmHash() => r'3717034c813e1d4cf8b2f212aa15ab483c6f220e';
 
 /// See also [NewsfeedPostVm].
 @ProviderFor(NewsfeedPostVm)
 final newsfeedPostVmProvider =
-    AutoDisposeNotifierProvider<NewsfeedPostVm, Object?>.internal(
+    AutoDisposeNotifierProvider<NewsfeedPostVm, NewsfeedPostPageState>.internal(
   NewsfeedPostVm.new,
   name: r'newsfeedPostVmProvider',
   debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
@@ -21,6 +21,6 @@ final newsfeedPostVmProvider =
   allTransitiveDependencies: null,
 );
 
-typedef _$NewsfeedPostVm = AutoDisposeNotifier<Object?>;
+typedef _$NewsfeedPostVm = AutoDisposeNotifier<NewsfeedPostPageState>;
 // ignore_for_file: type=lint
 // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 111 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_tabs.dart

@@ -0,0 +1,111 @@
+import 'package:cpt_community/modules/newsfeed/newsfeed_vm.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/my_appbar.dart';
+
+import '../community/community_vm.dart';
+import '../garagesale/garagesale_vm.dart';
+
+class NewsfeedTabs extends HookConsumerWidget {
+  List tabsList;
+  Widget? Function(BuildContext)? tabItemBuilder;
+  VoidCallback? onClickAction;
+  NewsfeedTabs({
+    Key? key,
+    required this.tabsList,
+    this.onClickAction,
+    this.tabItemBuilder
+  }) : super(key: key);
+
+  Widget _buildTabItem(BuildContext context, WidgetRef ref, vm, item, index) {
+    // 监听 activeIndex 的变化
+    final activeIndex = ref.watch(newsfeedVmProvider.select((state) => state.activeIndex));
+
+
+    return Container(
+      width: MediaQuery.of(context).size.width / vm.state.tabsList.length - 30,
+      height: 43,
+      padding: const EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
+      decoration: index==activeIndex? BoxDecoration(
+        color: index==activeIndex? context.appColors.btnBgDefault: ColorUtils.string2Color("#F2F3F6"),
+        borderRadius: BorderRadius.circular(20),
+        boxShadow: [
+          BoxShadow(
+            color: Colors.grey.withOpacity(0.5),
+            spreadRadius: 1,
+            blurRadius: 5,
+            offset: const Offset(0, 2), // changes position of shadow
+          ),
+        ],
+      ): null,
+      child: Row(
+        children: [
+          Expanded(
+            child: Container(
+              alignment: Alignment.center,
+              child: MyTextView(
+                item['title'],
+                fontSize: 16,
+                textAlign: TextAlign.center,
+                isFontMedium: true,
+                textColor: index == activeIndex ? Colors.white :ColorUtils.string2Color("#000000"),
+              ),
+            ),
+          ),
+        ],
+      ),
+    ).onTap((){
+      vm.handlerClickTab(index, item);
+    });
+  }
+
+  List<Widget> _buildTabs(BuildContext context, WidgetRef ref, vm){
+
+    int currentUseTag = ref.watch(newsfeedVmProvider.select((state) => state.useTag!));
+
+    List tabsList = ref.read(newsfeedVmProvider).tabsList;
+
+    int tabsLength = tabsList.length;
+
+    return List.generate(tabsLength, (index) {
+      return _buildTabItem(context, ref, vm, tabsList[index], index);
+    });
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final vm = ref.read(newsfeedVmProvider.notifier);
+    // 使用useEffect钩子
+    useEffect(() {
+      print('副作用函数执行');
+      // 这里是副作用逻辑
+      // vm.initPropData(tabsList, tabItemBuilder, onClickAction);
+      // 返回清理函数
+      return () {
+        print('清理函数执行');
+      };
+    }, []); // 空依赖列表意味着这个副作用只在组件挂载时执行一次
+
+    return SingleChildScrollView(
+      scrollDirection: Axis.horizontal,
+      physics: const BouncingScrollPhysics(),
+      clipBehavior: Clip.none,
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: _buildTabs(context, ref, vm),
+      ).constrained(
+          maxWidth:  MediaQuery.of(context).size.width
+      ),
+    );
+  }
+}

+ 53 - 1
packages/cpt_community/lib/modules/newsfeed/newsfeed_vm.dart

@@ -80,6 +80,50 @@ class NewsfeedVm extends _$NewsfeedVm {
             'isLike': false,
             'likeno': 12
           },
+          {
+            'id':4,
+            'avator': Assets.communityCamera,
+            'title': 'Fsjfkds  dfsk',
+            'isFollow': false,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': false,
+            'likeno': 12
+          },
+          {
+            'id':5,
+            'avator': Assets.communityCamera,
+            'title': 'Fsjfkds  dfsk',
+            'isFollow': false,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': false,
+            'likeno': 12
+          },
+          {
+            'id':6,
+            'avator': Assets.communityCamera,
+            'title': 'Fsjfkds  dfsk',
+            'isFollow': false,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': false,
+            'likeno': 12
+          },
+          {
+            'id':7,
+            'avator': Assets.communityCamera,
+            'title': '放大发大水',
+            'isFollow': false,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': false,
+            'likeno': 12
+          },
       ]
     );
   }
@@ -94,7 +138,7 @@ class NewsfeedVm extends _$NewsfeedVm {
 
   // 上拉加载
   Future onLoadData() async {
-    Log.d("----property_news_vm-----initListData");
+    Log.d("----newsfeed_vm-----initListData");
     // await Future.delayed(const Duration(seconds: 2));
     // if(state.list.length >= state.filterCount){
     //   return;
@@ -153,4 +197,12 @@ class NewsfeedVm extends _$NewsfeedVm {
 
     AutoRouter.of(context).pushNamed(RouterPath.newsFeedPost);
   }
+
+  // 点击tab
+  void handlerClickTab(int index, item){
+    state = state.copyWith(activeIndex: index);
+    print("切换后新的 sate, ${state.tabsList}");
+
+    // ref.invalidate(customTabsVmProvider);
+  }
 }

+ 1 - 1
packages/cpt_community/lib/modules/newsfeed/newsfeed_vm.g.dart

@@ -6,7 +6,7 @@ part of 'newsfeed_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$newsfeedVmHash() => r'f057a72e18926054b638eafd2ab1573f17f26000';
+String _$newsfeedVmHash() => r'8913ddbbe012f28caa65fbc8fdd824a8b818d4c6';
 
 /// See also [NewsfeedVm].
 @ProviderFor(NewsfeedVm)