Hero animation and scroll to position between two list in Flutter
this is what i've done, try:
import 'package:flutter/material.dart';import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); }}class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState();}class _HomePageState extends State<HomePage> { @override void initState() { super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: GridView.count( crossAxisCount: 3, children: List.generate(99, (index) { return Container( width: double.infinity, height: double.infinity, child: GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => ListPage(index: index)), ); }, child: Hero( tag: 'photo$index', child: Image.network( 'https://images.unsplash.com/photo-1628701621033-50564c683bb0?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80', fit: BoxFit.cover, ), ), ), ); }), ), ); }}class ListPage extends StatefulWidget { final int index; ListPage({Key key, @required this.index}) : super(key: key); @override _ListPageState createState() => _ListPageState();}class _ListPageState extends State<ListPage> { final ItemScrollController itemScrollController = ItemScrollController(); final ItemPositionsListener itemPositionsListener = ItemPositionsListener.create(); @override void initState() { super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return ScrollablePositionedList.builder( initialScrollIndex: widget.index, itemCount: 99, itemBuilder: (context, index) { return Column( children: [ AspectRatio( aspectRatio: 1, child: Hero( tag: 'photo$index', child: Image.network( 'https://images.unsplash.com/photo-1628701621033-50564c683bb0?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80', fit: BoxFit.cover, ), ), ), Container( height: 50, width: MediaQuery.of(context).size.width, child: Text('$index'), ), ], ); }, itemScrollController: itemScrollController, itemPositionsListener: itemPositionsListener, ); }}
Pass the selected item to destinate widget and build Hero
tag dynamically.
Main idea is to avoid too many matched Hero tags.
class MyImagesList extends Stateless Widget { final String selectedItem; final List<String> items; const MyImagesList(this.selectedItem, this.items); void build(BuildContext context) { return Column(children: [ for (var item in items) item == selectedItem ? Hero(tag: item, child: Text(item)) : Text(item) ]); }}