fix: no hero animation after tab change (#20285)

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
shenlong 2025-07-26 19:29:26 +05:30 committed by GitHub
parent d0576697c3
commit e85655d34c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 23 additions and 6 deletions

View File

@ -34,11 +34,13 @@ import 'package:platform/platform.dart';
class AssetViewerPage extends StatelessWidget {
final int initialIndex;
final TimelineService timelineService;
final int? heroOffset;
const AssetViewerPage({
super.key,
required this.initialIndex,
required this.timelineService,
this.heroOffset,
});
@override
@ -47,7 +49,7 @@ class AssetViewerPage extends StatelessWidget {
// since the Timeline and AssetViewer are on different routes / Widget subtrees.
return ProviderScope(
overrides: [timelineServiceProvider.overrideWithValue(timelineService)],
child: AssetViewer(initialIndex: initialIndex),
child: AssetViewer(initialIndex: initialIndex, heroOffset: heroOffset),
);
}
}
@ -55,11 +57,13 @@ class AssetViewerPage extends StatelessWidget {
class AssetViewer extends ConsumerStatefulWidget {
final int initialIndex;
final Platform? platform;
final int? heroOffset;
const AssetViewer({
super.key,
required this.initialIndex,
this.platform,
this.heroOffset,
});
@override
@ -108,7 +112,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
_onAssetChanged(widget.initialIndex);
});
reloadSubscription = EventStream.shared.listen(_onEvent);
heroOffset = TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
heroOffset = widget.heroOffset ?? TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
}
@override

View File

@ -15,6 +15,7 @@ class ThumbnailTile extends ConsumerWidget {
this.fit = BoxFit.cover,
this.showStorageIndicator = true,
this.lockSelection = false,
this.heroOffset,
super.key,
});
@ -23,10 +24,11 @@ class ThumbnailTile extends ConsumerWidget {
final BoxFit fit;
final bool showStorageIndicator;
final bool lockSelection;
final int? heroOffset;
@override
Widget build(BuildContext context, WidgetRef ref) {
final heroOffset = TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
final heroIndex = heroOffset ?? TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
final assetContainerColor =
context.isDarkTheme ? context.primaryColor.darken(amount: 0.4) : context.primaryColor.lighten(amount: 0.75);
@ -67,7 +69,7 @@ class ThumbnailTile extends ConsumerWidget {
children: [
Positioned.fill(
child: Hero(
tag: '${asset.heroTag}_$heroOffset',
tag: '${asset.heroTag}_$heroIndex',
child: Thumbnail(
asset: asset,
fit: fit,

View File

@ -162,6 +162,7 @@ class _AssetTileWidget extends ConsumerWidget {
WidgetRef ref,
int assetIndex,
BaseAsset asset,
int? heroOffset,
) async {
final multiSelectState = ref.read(multiSelectProvider);
@ -174,6 +175,7 @@ class _AssetTileWidget extends ConsumerWidget {
AssetViewerRoute(
initialIndex: assetIndex,
timelineService: ref.read(timelineServiceProvider),
heroOffset: heroOffset,
),
);
}
@ -205,6 +207,8 @@ class _AssetTileWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final heroOffset = TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
final lockSelection = _getLockSelectionStatus(ref);
final showStorageIndicator = ref.watch(
timelineArgsProvider.select((args) => args.showStorageIndicator),
@ -212,12 +216,13 @@ class _AssetTileWidget extends ConsumerWidget {
return RepaintBoundary(
child: GestureDetector(
onTap: () => lockSelection ? null : _handleOnTap(context, ref, assetIndex, asset),
onTap: () => lockSelection ? null : _handleOnTap(context, ref, assetIndex, asset, heroOffset),
onLongPress: () => lockSelection ? null : _handleOnLongPress(ref, asset),
child: ThumbnailTile(
asset,
lockSelection: lockSelection,
showStorageIndicator: showStorageIndicator,
heroOffset: heroOffset,
),
),
);

View File

@ -399,6 +399,7 @@ class AssetViewerRoute extends PageRouteInfo<AssetViewerRouteArgs> {
Key? key,
required int initialIndex,
required TimelineService timelineService,
int? heroOffset,
List<PageRouteInfo>? children,
}) : super(
AssetViewerRoute.name,
@ -406,6 +407,7 @@ class AssetViewerRoute extends PageRouteInfo<AssetViewerRouteArgs> {
key: key,
initialIndex: initialIndex,
timelineService: timelineService,
heroOffset: heroOffset,
),
initialChildren: children,
);
@ -420,6 +422,7 @@ class AssetViewerRoute extends PageRouteInfo<AssetViewerRouteArgs> {
key: args.key,
initialIndex: args.initialIndex,
timelineService: args.timelineService,
heroOffset: args.heroOffset,
);
},
);
@ -430,6 +433,7 @@ class AssetViewerRouteArgs {
this.key,
required this.initialIndex,
required this.timelineService,
this.heroOffset,
});
final Key? key;
@ -438,9 +442,11 @@ class AssetViewerRouteArgs {
final TimelineService timelineService;
final int? heroOffset;
@override
String toString() {
return 'AssetViewerRouteArgs{key: $key, initialIndex: $initialIndex, timelineService: $timelineService}';
return 'AssetViewerRouteArgs{key: $key, initialIndex: $initialIndex, timelineService: $timelineService, heroOffset: $heroOffset}';
}
}