fix tab switcher scroll flickering

This commit is contained in:
Fabian Freund
2026-05-29 08:23:52 +02:00
parent 4a20615842
commit e2224f1049
@@ -670,6 +670,10 @@ class QuickTabSwitcher extends HookConsumerWidget {
final activeItemKey = useRef(GlobalKey()); final activeItemKey = useRef(GlobalKey());
final isUserScrolling = useRef(false); final isUserScrolling = useRef(false);
final userScrollTimer = useRef<Timer?>(null); final userScrollTimer = useRef<Timer?>(null);
final didRunInitialAutoScroll = useRef(false);
final scrollKey = PageStorageKey(
'quick_tab_switcher_${quickTabSwitcherMode.name}',
);
useEffect(() { useEffect(() {
return userScrollTimer.value?.cancel; return userScrollTimer.value?.cancel;
@@ -678,7 +682,16 @@ class QuickTabSwitcher extends HookConsumerWidget {
useEffect(() { useEffect(() {
if (isUserScrolling.value) return null; if (isUserScrolling.value) return null;
final isInitialAutoScroll = !didRunInitialAutoScroll.value;
didRunInitialAutoScroll.value = true;
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (isInitialAutoScroll &&
chipScrollController.hasClients &&
chipScrollController.offset != 0) {
return;
}
final context = activeItemKey.value.currentContext; final context = activeItemKey.value.currentContext;
if (context != null) { if (context != null) {
unawaited( unawaited(
@@ -744,6 +757,7 @@ class QuickTabSwitcher extends HookConsumerWidget {
reorderableItemCount: reorderEnabled ? tabItems.length : 0, reorderableItemCount: reorderEnabled ? tabItems.length : 0,
activeItem: (activeItem?.isActive ?? false) ? activeItem : null, activeItem: (activeItem?.isActive ?? false) ? activeItem : null,
scrollController: chipScrollController, scrollController: chipScrollController,
scrollKey: scrollKey,
activeItemKey: activeItemKey.value, activeItemKey: activeItemKey.value,
showTitles: showTitles, showTitles: showTitles,
showIsolatedTabUi: showIsolatedTabUi, showIsolatedTabUi: showIsolatedTabUi,
@@ -814,6 +828,7 @@ class QuickTabSwitcherView extends StatelessWidget {
required this.availableItems, required this.availableItems,
required this.activeItem, required this.activeItem,
required this.scrollController, required this.scrollController,
this.scrollKey,
this.activeItemKey, this.activeItemKey,
required this.showTitles, required this.showTitles,
required this.showIsolatedTabUi, required this.showIsolatedTabUi,
@@ -826,6 +841,7 @@ class QuickTabSwitcherView extends StatelessWidget {
final List<QuickTabSwitcherItem> availableItems; final List<QuickTabSwitcherItem> availableItems;
final QuickTabSwitcherItem? activeItem; final QuickTabSwitcherItem? activeItem;
final ScrollController scrollController; final ScrollController scrollController;
final Key? scrollKey;
final GlobalKey? activeItemKey; final GlobalKey? activeItemKey;
final bool showTitles; final bool showTitles;
final bool showIsolatedTabUi; final bool showIsolatedTabUi;
@@ -867,6 +883,7 @@ class QuickTabSwitcherView extends StatelessWidget {
sortSelectedFirst: false, sortSelectedFirst: false,
maxCount: null, maxCount: null,
scrollController: scrollController, scrollController: scrollController,
scrollKey: scrollKey,
activeItemKey: activeItemKey, activeItemKey: activeItemKey,
cacheExtent: 500, cacheExtent: 500,
itemId: (item) => item.id, itemId: (item) => item.id,
@@ -892,6 +909,7 @@ class QuickTabSwitcherView extends StatelessWidget {
); );
return ReorderableListView.builder( return ReorderableListView.builder(
key: scrollKey,
scrollController: scrollController, scrollController: scrollController,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
buildDefaultDragHandles: true, buildDefaultDragHandles: true,