@@ -41,6 +41,7 @@ class TabBarViewPageState extends State<TabBarViewPage>
41
41
header: ClassicHeader (
42
42
clamping: true ,
43
43
position: IndicatorPosition .locator,
44
+ mainAxisAlignment: MainAxisAlignment .end,
44
45
dragText: 'Pull to refresh' .tr,
45
46
armedText: 'Release ready' .tr,
46
47
readyText: 'Refreshing...' .tr,
@@ -88,94 +89,123 @@ class TabBarViewPageState extends State<TabBarViewPage>
88
89
});
89
90
},
90
91
childBuilder: (context, physics) {
91
- return ExtendedNestedScrollView (
92
- physics: physics,
93
- onlyOneScrollInBody: true ,
94
- pinnedHeaderSliverHeightBuilder: () {
95
- return MediaQuery .of (context).padding.top + kToolbarHeight;
96
- },
97
- headerSliverBuilder: (context, innerBoxIsScrolled) {
98
- return < Widget > [
99
- const HeaderLocator .sliver (clearExtent: false ),
100
- SliverAppBar (
101
- expandedHeight: 166 ,
102
- pinned: true ,
103
- flexibleSpace: FlexibleSpaceBar (
104
- title: Text (
105
- 'TabBarView' ,
106
- style: TextStyle (
107
- color: Theme .of (context).textTheme.titleLarge? .color),
92
+ return ScrollConfiguration (
93
+ behavior: const ERScrollBehavior (),
94
+ child: ExtendedNestedScrollView (
95
+ physics: physics,
96
+ onlyOneScrollInBody: true ,
97
+ pinnedHeaderSliverHeightBuilder: () {
98
+ return MediaQuery .of (context).padding.top + kToolbarHeight;
99
+ },
100
+ headerSliverBuilder: (context, innerBoxIsScrolled) {
101
+ return < Widget > [
102
+ const HeaderLocator .sliver (clearExtent: false ),
103
+ SliverAppBar (
104
+ expandedHeight: 120 ,
105
+ pinned: true ,
106
+ flexibleSpace: FlexibleSpaceBar (
107
+ title: Text (
108
+ 'TabBarView' ,
109
+ style: TextStyle (
110
+ color:
111
+ Theme .of (context).textTheme.titleLarge? .color),
112
+ ),
113
+ centerTitle: false ,
108
114
),
109
- titlePadding: const EdgeInsets .only (left: 64 , bottom: 60 ),
110
- centerTitle: false ,
111
115
),
112
- bottom: PreferredSize (
113
- child: Padding (
114
- padding: const EdgeInsets .symmetric (
115
- horizontal: 8 ,
116
+ ];
117
+ },
118
+ body: Column (
119
+ children: [
120
+ TabBar (
121
+ controller: _tabController,
122
+ labelColor: themeData.colorScheme.primary,
123
+ indicatorColor: themeData.colorScheme.primary,
124
+ tabs: const < Widget > [
125
+ Tab (
126
+ text: 'List' ,
116
127
),
117
- child: TabBar (
118
- controller: _tabController,
119
- labelColor: themeData.colorScheme.primary,
120
- indicatorColor: themeData.colorScheme.primary,
121
- tabs: const < Widget > [
122
- Tab (
123
- text: 'List' ,
124
- ),
125
- Tab (
126
- text: 'Grid' ,
127
- ),
128
- ],
128
+ Tab (
129
+ text: 'Grid' ,
129
130
),
130
- ),
131
- preferredSize: const Size (double .infinity, 46 ),
132
- ),
133
- ),
134
- ];
135
- },
136
- body: TabBarView (
137
- controller: _tabController,
138
- children: < Widget > [
139
- ExtendedVisibilityDetector (
140
- uniqueKey: const Key ('Tab0' ),
141
- child: CustomScrollView (
142
- physics: physics,
143
- slivers: [
144
- SliverList (
145
- delegate:
146
- SliverChildBuilderDelegate ((context, index) {
147
- return const SkeletonItem ();
148
- }, childCount: _listCount)),
149
- const FooterLocator .sliver (),
150
131
],
151
132
),
152
- ),
153
- ExtendedVisibilityDetector (
154
- uniqueKey: const Key ('Tab1' ),
155
- child: CustomScrollView (
156
- physics: physics,
157
- slivers: [
158
- SliverGrid (
159
- delegate:
160
- SliverChildBuilderDelegate ((context, index) {
161
- return const SkeletonItem (
162
- direction: Axis .horizontal,
163
- );
164
- }, childCount: _gridCount),
165
- gridDelegate:
166
- const SliverGridDelegateWithFixedCrossAxisCount (
167
- crossAxisCount: 2 ,
168
- childAspectRatio: 6 / 7 ,
169
- )),
170
- const FooterLocator .sliver (),
171
- ],
133
+ Expanded (
134
+ child: TabBarView (
135
+ controller: _tabController,
136
+ children: < Widget > [
137
+ ExtendedVisibilityDetector (
138
+ uniqueKey: const Key ('Tab0' ),
139
+ child: _AutomaticKeepAlive (
140
+ child: CustomScrollView (
141
+ physics: physics,
142
+ slivers: [
143
+ SliverList (
144
+ delegate: SliverChildBuilderDelegate (
145
+ (context, index) {
146
+ return const SkeletonItem ();
147
+ }, childCount: _listCount)),
148
+ const FooterLocator .sliver (),
149
+ ],
150
+ ),
151
+ ),
152
+ ),
153
+ ExtendedVisibilityDetector (
154
+ uniqueKey: const Key ('Tab1' ),
155
+ child: _AutomaticKeepAlive (
156
+ child: CustomScrollView (
157
+ physics: physics,
158
+ slivers: [
159
+ SliverGrid (
160
+ delegate: SliverChildBuilderDelegate (
161
+ (context, index) {
162
+ return const SkeletonItem (
163
+ direction: Axis .horizontal,
164
+ );
165
+ }, childCount: _gridCount),
166
+ gridDelegate:
167
+ const SliverGridDelegateWithFixedCrossAxisCount (
168
+ crossAxisCount: 2 ,
169
+ childAspectRatio: 6 / 7 ,
170
+ )),
171
+ const FooterLocator .sliver (),
172
+ ],
173
+ ),
174
+ ),
175
+ ),
176
+ ],
177
+ ),
172
178
),
173
- ) ,
174
- ] ,
179
+ ] ,
180
+ ) ,
175
181
),
176
182
);
177
183
},
178
184
),
179
185
);
180
186
}
181
187
}
188
+
189
+ class _AutomaticKeepAlive extends StatefulWidget {
190
+ final Widget child;
191
+
192
+ const _AutomaticKeepAlive ({
193
+ Key ? key,
194
+ required this .child,
195
+ }) : super (key: key);
196
+
197
+ @override
198
+ State <_AutomaticKeepAlive > createState () => _AutomaticKeepAliveState ();
199
+ }
200
+
201
+ class _AutomaticKeepAliveState extends State <_AutomaticKeepAlive >
202
+ with AutomaticKeepAliveClientMixin {
203
+ @override
204
+ Widget build (BuildContext context) {
205
+ super .build (context);
206
+ return widget.child;
207
+ }
208
+
209
+ @override
210
+ bool get wantKeepAlive => true ;
211
+ }
0 commit comments