@@ -24,6 +24,7 @@ class InnerInfiniteScrollTabView extends StatefulWidget {
24
24
this .backgroundColor,
25
25
this .onPageChanged,
26
26
required this .indicatorColor,
27
+ this .indicatorHeight,
27
28
required this .defaultLocale,
28
29
required this .tabHeight,
29
30
required this .tabPadding,
@@ -41,6 +42,7 @@ class InnerInfiniteScrollTabView extends StatefulWidget {
41
42
final Color ? backgroundColor;
42
43
final ValueChanged <int >? onPageChanged;
43
44
final Color indicatorColor;
45
+ final double ? indicatorHeight;
44
46
final Locale defaultLocale;
45
47
final double tabHeight;
46
48
final double tabPadding;
@@ -58,7 +60,7 @@ class InnerInfiniteScrollTabViewState extends State<InnerInfiniteScrollTabView>
58
60
);
59
61
late final _pageController = CycledScrollController ();
60
62
61
- bool _isContentChangingByTab = false ;
63
+ final ValueNotifier < bool > _isContentChangingByTab = ValueNotifier ( false ) ;
62
64
bool _isTabForceScrolling = false ;
63
65
64
66
late double _previousTextScaleFactor = widget.textScaleFactor;
@@ -85,7 +87,8 @@ class InnerInfiniteScrollTabViewState extends State<InnerInfiniteScrollTabView>
85
87
final List <Tween <double >> _tabSizeTweens = [];
86
88
List <Tween <double >> get tabSizeTweens => _tabSizeTweens;
87
89
88
- double get indicatorWidth => widget.separator? .width ?? 2.0 ;
90
+ double get indicatorWidth =>
91
+ widget.indicatorHeight ?? widget.separator? .width ?? 2.0 ;
89
92
90
93
late final _indicatorAnimationController =
91
94
AnimationController (vsync: this , duration: _tabAnimationDuration)
@@ -182,7 +185,7 @@ class InnerInfiniteScrollTabViewState extends State<InnerInfiniteScrollTabView>
182
185
});
183
186
184
187
_pageController.addListener (() {
185
- if (_isContentChangingByTab) return ;
188
+ if (_isContentChangingByTab.value ) return ;
186
189
187
190
final currentIndexDouble = _pageController.offset / widget.size.width;
188
191
final currentIndex = currentIndexDouble.floor ();
@@ -210,11 +213,12 @@ class InnerInfiniteScrollTabViewState extends State<InnerInfiniteScrollTabView>
210
213
}
211
214
212
215
void _onTapTab (int modIndex, int rawIndex) async {
216
+ _isContentChangingByTab.value = true ;
217
+
213
218
widget.onTabTap? .call (modIndex);
214
219
widget.onPageChanged? .call (modIndex);
215
220
216
221
HapticFeedback .selectionClick ();
217
- _selectedIndex.value = modIndex;
218
222
_isTabPositionAligned.value = true ;
219
223
220
224
final sizeOnIndex = _calculateTabSizeFromIndex (modIndex);
@@ -236,25 +240,24 @@ class InnerInfiniteScrollTabViewState extends State<InnerInfiniteScrollTabView>
236
240
.animate (_indicatorAnimationController);
237
241
_indicatorAnimationController.forward (from: 0 );
238
242
239
- _isContentChangingByTab = true ;
240
243
// 現在のスクロール位置とページインデックスを取得
241
244
final currentOffset = _pageController.offset;
242
- final currentModIndex =
243
- (currentOffset ~ / widget.size.width) % widget.contentLength;
244
245
245
246
// 選択したページまでの距離を計算する
246
247
// modの境界をまたぐ場合を考慮して、近い方向を指すように正負を調整する
247
248
final move = calculateMoveIndexDistance (
248
- currentModIndex , modIndex, widget.contentLength);
249
+ _selectedIndex.value , modIndex, widget.contentLength);
249
250
final targetPageOffset = currentOffset + move * widget.size.width;
250
251
252
+ _selectedIndex.value = modIndex;
253
+
251
254
await _pageController.animateTo (
252
255
targetPageOffset,
253
256
duration: _tabAnimationDuration,
254
257
curve: Curves .ease,
255
258
);
256
259
257
- _isContentChangingByTab = false ;
260
+ _isContentChangingByTab.value = false ;
258
261
}
259
262
260
263
@override
@@ -265,35 +268,12 @@ class InnerInfiniteScrollTabViewState extends State<InnerInfiniteScrollTabView>
265
268
children: [
266
269
SizedBox (
267
270
height: widget.tabHeight + (widget.separator? .width ?? 0 ),
268
- child: CycledListView .builder (
269
- scrollDirection: Axis .horizontal,
270
- controller: _tabController,
271
- contentCount: widget.contentLength,
272
- itemBuilder: (context, modIndex, rawIndex) {
273
- return Material (
274
- color: widget.backgroundColor,
275
- child: InkWell (
276
- onTap: () => _onTapTab (modIndex, rawIndex),
277
- child: ValueListenableBuilder <int >(
278
- valueListenable: _selectedIndex,
279
- builder: (context, index, _) =>
280
- ValueListenableBuilder <bool >(
281
- valueListenable: _isTabPositionAligned,
282
- builder: (context, tab, _) => _TabContent (
283
- isTabPositionAligned: tab,
284
- selectedIndex: index,
285
- indicatorColor: widget.indicatorColor,
286
- tabPadding: widget.tabPadding,
287
- modIndex: modIndex,
288
- tabBuilder: widget.tabBuilder,
289
- separator: widget.separator,
290
- indicatorWidth: indicatorWidth,
291
- ),
292
- ),
293
- ),
294
- ),
295
- );
296
- },
271
+ child: ValueListenableBuilder <bool >(
272
+ valueListenable: _isContentChangingByTab,
273
+ builder: (context, value, _) => AbsorbPointer (
274
+ absorbing: value,
275
+ child: _buildTabSection (),
276
+ ),
297
277
),
298
278
),
299
279
Positioned (
@@ -334,6 +314,38 @@ class InnerInfiniteScrollTabViewState extends State<InnerInfiniteScrollTabView>
334
314
);
335
315
}
336
316
317
+ Widget _buildTabSection () {
318
+ return CycledListView .builder (
319
+ scrollDirection: Axis .horizontal,
320
+ controller: _tabController,
321
+ contentCount: widget.contentLength,
322
+ itemBuilder: (context, modIndex, rawIndex) {
323
+ return Material (
324
+ color: widget.backgroundColor,
325
+ child: InkWell (
326
+ onTap: () => _onTapTab (modIndex, rawIndex),
327
+ child: ValueListenableBuilder <int >(
328
+ valueListenable: _selectedIndex,
329
+ builder: (context, index, _) => ValueListenableBuilder <bool >(
330
+ valueListenable: _isTabPositionAligned,
331
+ builder: (context, tab, _) => _TabContent (
332
+ isTabPositionAligned: tab,
333
+ selectedIndex: index,
334
+ indicatorColor: widget.indicatorColor,
335
+ tabPadding: widget.tabPadding,
336
+ modIndex: modIndex,
337
+ tabBuilder: widget.tabBuilder,
338
+ separator: widget.separator,
339
+ indicatorWidth: indicatorWidth,
340
+ ),
341
+ ),
342
+ ),
343
+ ),
344
+ );
345
+ },
346
+ );
347
+ }
348
+
337
349
@override
338
350
void dispose () {
339
351
_tabController.dispose ();
0 commit comments