Skip to content

Commit 8fd0ac0

Browse files
committed
update: example
1 parent 4ba7024 commit 8fd0ac0

23 files changed

+1512
-0
lines changed

example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
buildConfiguration = "Debug"
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
2930
shouldUseLaunchSchemeArgsEnv = "YES">
3031
<MacroExpansion>
3132
<BuildableReference
@@ -43,6 +44,7 @@
4344
buildConfiguration = "Debug"
4445
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
4546
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
47+
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
4648
launchStyle = "0"
4749
useCustomWorkingDirectory = "NO"
4850
ignoresPersistentStateOnLaunch = "NO"

example/lib/common/route/router_config.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import 'package:scrollview_observer_example/features/scene/anchor_demo/anchor_wa
3535
import 'package:scrollview_observer_example/features/scene/azlist_demo/azlist_page.dart';
3636
import 'package:scrollview_observer_example/features/scene/chat_demo/page/chat_gpt_page.dart';
3737
import 'package:scrollview_observer_example/features/scene/chat_demo/page/chat_page.dart';
38+
import 'package:scrollview_observer_example/features/scene/detail/page/detail_page.dart';
3839
import 'package:scrollview_observer_example/features/scene/expandable_carousel_slider_demo/expandable_carousel_slider_demo.dart';
3940
import 'package:scrollview_observer_example/features/scene/image_tab_demo/image_tab_page.dart';
4041
import 'package:scrollview_observer_example/features/scene/scrollview_form_demo/scrollview_form_demo_page.dart';
@@ -88,6 +89,7 @@ class MyPage {
8889
static const visibilityScrollView = '/visibility_scroll_view';
8990
static const azList = '/az_list';
9091
static const expandableCarouselSlider = '/expandable_carousel_slider';
92+
static const detail = '/detail';
9193
}
9294

9395
class MyRoute {
@@ -248,5 +250,9 @@ class MyRoute {
248250
path: MyPage.expandableCarouselSlider,
249251
builder: (context, state) => const ExpandableCarouselSliderDemo(),
250252
),
253+
GoRoute(
254+
path: MyPage.detail,
255+
builder: (context, state) => const DetailPage(),
256+
),
251257
];
252258
}

example/lib/features/home/home_page.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,12 @@ class HomePage extends StatelessWidget {
231231
NavigationService.push(MyPage.expandableCarouselSlider);
232232
},
233233
),
234+
ListTile(
235+
title: const Text("Detail Page"),
236+
onTap: () {
237+
NavigationService.push(MyPage.detail);
238+
},
239+
),
234240
],
235241
);
236242
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* @Author: LinXunFeng [email protected]
3+
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
4+
* @Date: 2025-08-02 19:57:05
5+
*/
6+
7+
import 'package:flutter/material.dart';
8+
import 'package:getx_helper/getx_helper.dart';
9+
import 'package:scrollview_observer_example/features/scene/detail/logic/detail_logic.dart';
10+
11+
typedef DetailLogicPutMixin<W extends StatefulWidget>
12+
= GetxLogicPutStateMixin<DetailLogic, W>;
13+
14+
typedef DetailLogicConsumerMixin<W extends StatefulWidget>
15+
= GetxLogicConsumerStateMixin<DetailLogic, W>;
16+
17+
enum DetailUpdateType {
18+
navBar,
19+
}
20+
21+
enum DetailModuleType {
22+
module1,
23+
module2,
24+
module3,
25+
module4,
26+
module5,
27+
module6,
28+
module7,
29+
module8,
30+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* @Author: LinXunFeng [email protected]
3+
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
4+
* @Date: 2025-08-02 19:57:05
5+
*/
6+
7+
import 'package:get/get.dart';
8+
import 'package:scrollview_observer_example/features/scene/detail/logic/detail_logic_list_view.dart';
9+
import 'package:scrollview_observer_example/features/scene/detail/logic/detail_logic_nav_bar.dart';
10+
import 'package:scrollview_observer_example/features/scene/detail/state/detail_state.dart';
11+
12+
class DetailLogic extends GetxController with GetTickerProviderStateMixin {
13+
final DetailState state = DetailState();
14+
15+
@override
16+
void onInit() {
17+
super.onInit();
18+
19+
onInitForNavBar();
20+
onInitForListView();
21+
}
22+
23+
void onDispose() {
24+
onDisposeForNavBar();
25+
onDisposeForListView();
26+
}
27+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* @Author: LinXunFeng [email protected]
3+
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
4+
* @Date: 2025-08-03 21:02:30
5+
*/
6+
7+
import 'package:scrollview_observer/scrollview_observer.dart';
8+
import 'package:scrollview_observer_example/features/scene/detail/logic/detail_logic.dart';
9+
import 'package:scrollview_observer_example/features/scene/detail/logic/detail_logic_nav_bar.dart';
10+
11+
extension DetailLogicForListView on DetailLogic {
12+
void onInitForListView() {
13+
state.scrollController.addListener(() {
14+
if (!state.scrollController.hasClients) return;
15+
updateNavBarAlpha();
16+
});
17+
}
18+
19+
void onDisposeForListView() {
20+
state.scrollController.dispose();
21+
}
22+
23+
void onObserveForListView(ListViewObserveModel result) {
24+
final navBarTabController = state.navBarTabController;
25+
if (navBarTabController == null) return;
26+
27+
navBarTabController.index = ObserverUtils.calcAnchorTabIndex(
28+
observeModel: result,
29+
tabIndexs: state.navBarTabs.map((e) => e.index).toList(),
30+
currentTabIndex: navBarTabController.index,
31+
);
32+
}
33+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* @Author: LinXunFeng [email protected]
3+
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
4+
* @Date: 2025-08-03 21:06:31
5+
*/
6+
7+
import 'dart:math';
8+
9+
import 'package:flutter/material.dart';
10+
import 'package:scrollview_observer_example/features/scene/detail/header/detail_header.dart';
11+
import 'package:scrollview_observer_example/features/scene/detail/logic/detail_logic.dart';
12+
import 'package:scrollview_observer_example/features/scene/detail/model/detail_nav_bar_tab_model.dart';
13+
14+
extension DetailLogicForNavBar on DetailLogic {
15+
void onInitForNavBar() {
16+
state.navBarTabs = [
17+
createNavBarTabModel(DetailModuleType.module1),
18+
createNavBarTabModel(DetailModuleType.module4),
19+
createNavBarTabModel(DetailModuleType.module7),
20+
];
21+
state.navBarTabController = TabController(
22+
length: state.navBarTabs.length,
23+
vsync: this,
24+
);
25+
}
26+
27+
DetailNavBarTabModel createNavBarTabModel(
28+
DetailModuleType type,
29+
) {
30+
return DetailNavBarTabModel(
31+
type: type,
32+
index: state.moduleTypes.indexOf(type),
33+
);
34+
}
35+
36+
void onDisposeForNavBar() {
37+
state.navBarTabController?.dispose();
38+
state.navBarTabController = null;
39+
}
40+
41+
void handleNavBarTabTap(int index) {
42+
if (!state.scrollController.hasClients) return;
43+
44+
final tabModel = state.navBarTabs[index];
45+
final moduleIndex = tabModel.index;
46+
if (moduleIndex == 0) {
47+
state.scrollController.jumpTo(0);
48+
return;
49+
}
50+
state.observerController.jumpTo(
51+
index: moduleIndex,
52+
offset: (_) => state.navBarHeight,
53+
);
54+
}
55+
56+
void updateNavBarAlpha() {
57+
if (!state.scrollController.position.hasPixels) return;
58+
state.scrollController.position.pixels;
59+
60+
state.navBarHeight;
61+
state.navBarAlpha;
62+
63+
final scrollOffset = state.scrollController.position.pixels;
64+
final navBarHeight = state.navBarHeight;
65+
66+
double newAlpha = 0.0;
67+
newAlpha = min(
68+
1.0,
69+
max(0.0, scrollOffset / navBarHeight),
70+
);
71+
72+
if (state.navBarAlpha == newAlpha) return;
73+
state.navBarAlpha = newAlpha;
74+
update([
75+
DetailUpdateType.navBar,
76+
]);
77+
}
78+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* @Author: LinXunFeng [email protected]
3+
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
4+
* @Date: 2025-08-04 22:18:57
5+
*/
6+
7+
import 'package:scrollview_observer_example/features/scene/detail/header/detail_header.dart';
8+
9+
class DetailNavBarTabModel {
10+
final DetailModuleType type;
11+
12+
final int index;
13+
14+
String get title => '${type.name[0].toUpperCase()}${type.name.substring(1)}';
15+
16+
DetailNavBarTabModel({
17+
required this.type,
18+
required this.index,
19+
});
20+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* @Author: LinXunFeng [email protected]
3+
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
4+
* @Date: 2025-08-02 19:57:05
5+
*/
6+
7+
import 'package:flutter/material.dart';
8+
import 'package:get/get.dart';
9+
import 'package:scrollview_observer_example/features/scene/detail/header/detail_header.dart';
10+
import 'package:scrollview_observer_example/features/scene/detail/logic/detail_logic.dart';
11+
import 'package:scrollview_observer_example/features/scene/detail/state/detail_state.dart';
12+
import 'package:scrollview_observer_example/features/scene/detail/widget/detail_list_view.dart';
13+
import 'package:scrollview_observer_example/features/scene/detail/widget/detail_nav_bar.dart';
14+
15+
class DetailPage extends StatefulWidget {
16+
const DetailPage({super.key});
17+
18+
@override
19+
State<DetailPage> createState() => DetailPageState();
20+
}
21+
22+
class DetailPageState extends State<DetailPage>
23+
with DetailLogicPutMixin<DetailPage> {
24+
DetailState get state => logic.state;
25+
26+
@override
27+
void dispose() {
28+
logic.onDispose();
29+
super.dispose();
30+
}
31+
32+
@override
33+
DetailLogic initLogic() => DetailLogic();
34+
35+
@override
36+
Widget buildBody(BuildContext context) {
37+
return GetBuilder<DetailLogic>(
38+
tag: logicTag,
39+
assignId: true,
40+
builder: (_) {
41+
return Scaffold(
42+
appBar: _buildAppBar(),
43+
body: _buildBody(),
44+
);
45+
},
46+
);
47+
}
48+
49+
AppBar _buildAppBar() {
50+
return AppBar(
51+
title: const Text('Detail Page'),
52+
);
53+
}
54+
55+
Widget _buildBody() {
56+
return const Stack(
57+
children: [
58+
DetailListView(),
59+
Positioned(
60+
top: 0,
61+
left: 0,
62+
right: 0,
63+
child: DetailNavBar(),
64+
),
65+
],
66+
);
67+
}
68+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* @Author: LinXunFeng [email protected]
3+
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
4+
* @Date: 2025-08-02 19:57:05
5+
*/
6+
7+
import 'package:scrollview_observer_example/features/scene/detail/state/detail_state_list_view.dart';
8+
import 'package:scrollview_observer_example/features/scene/detail/state/detail_state_nav_bar.dart';
9+
10+
class DetailState with DetailStateForNavBar, DetailStateForListView {}

0 commit comments

Comments
 (0)