我正在尝试将 Hero Widget 和 Carousel 集成到 flutter 中。
我有一个产品列表,onTap 产品的图像通过 Hero Widget 动画到详细信息页面。
我已经能够在没有轮播的情况下成功实现英雄小部件,但是在详细信息页面上,我希望能够使用轮播查看同一产品的不同图片。
我怎样才能使轮播上的第一个项目与之前的页面具有相同的英雄标签,如下图所示?
第 1 页
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailsPage(
url: widget.url,
title: widget.url,
index: widget.index)),
);
},
child: Hero(
tag: "product-image+${widget.index}",
child: Container(
padding: EdgeInsets.all(16.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10)),
child: FadeInImage.memoryNetwork(
placeholder: kTransparentImage,
image:
'https://i.dlpng.com/static/png/6838599_preview.png',
),
),
))),
详情页import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
class DetailsPage extends StatefulWidget {
final String url;
final String title;
final int index;
DetailsPage({this.url, this.title, this.index});
@override
_DetailsPageState createState() => _DetailsPageState();
}
class _DetailsPageState extends State<DetailsPage> {
List imgList = [
'https://i.dlpng.com/static/png/6838599_preview.png',
'https://i.dlpng.com/static/png/6838599_preview.png',
'https://i.dlpng.com/static/png/6838599_preview.png',
'https://i.dlpng.com/static/png/6838599_preview.png',
];
int _current = 0;
List<T> map<T>(List list, Function handler) {
List<T> result = [];
for (var i = 0; i < list.length; i++) {
result.add(handler(i, list[i]));
}
return result;
}
@override
Widget build(BuildContext context) {
final double height = MediaQuery.of(context).size.height;
return Scaffold(
backgroundColor: Theme.of(context).canvasColor,
appBar: AppBar(
title: Center(
child: Text(
'Details',
style: TextStyle(
fontFamily: 'OpenSansLight',
fontSize: 26,
color: Theme.of(context).textTheme.headline1.color),
),
),
elevation: 0,
backgroundColor: Theme.of(context).canvasColor,
leading: IconButton(
icon: Icon(Icons.arrow_back,
color: Theme.of(context).iconTheme.color),
onPressed: () {
Navigator.of(context).pop();
}),
),
body: Container(
height: height,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Hero(
tag: "product-image+${widget.index}",
child: Container(
padding: EdgeInsets.all(8.0),
height: 200.0,
alignment: Alignment.topCenter,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
widget.url ??
'https://i.dlpng.com/static/png/6838599_preview.png',
),
fit: BoxFit.contain)),
),
),
CarouselSlider(
options: CarouselOptions(
height: 200.0,
initialPage: 0,
reverse: false,
autoPlay: false,
enableInfiniteScroll: false,
scrollDirection: Axis.horizontal,
onPageChanged: (index, fn) {
setState(() {
_current = index;
});
}),
items: imgList.map((imgUrl) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(10),),
child:
Image.network(
imgUrl,
fit: BoxFit.cover,
),
);
},
);
}).toList(),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(imgList, (index, url) {
return Container(
width: 30.0,
height: 2.0,
margin:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 4.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
color:
_current == index ? Colors.deepPurple : Colors.grey,
),
);
}),
),
],
),
),
),
);
}
}
最佳答案
一个相当愚蠢的问题。我不假思索地做到了。我刚刚将 Hero Widget 包裹在 Carousel slider 上
Container(
height: height,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: <Widget>[
Hero(
tag: "product-image+${widget.index}",
child: CarouselSlider(
options: CarouselOptions(
height: 200.0,
enlargeCenterPage: true,
enlargeStrategy: CenterPageEnlargeStrategy.height,
initialPage: 0,
reverse: false,
autoPlay: false,
enableInfiniteScroll: false,
scrollDirection: Axis.horizontal,
onPageChanged: (index, fn) {
setState(() {
_current = index;
});
}),
items: imgList.map((imgUrl) {
return Builder(
builder: (BuildContext context) {
return Image.network(
imgUrl,
fit: BoxFit.cover,
);
},
);
}).toList(),
),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(imgList, (index, url) {
return Container(
width: 30.0,
height: 2.0,
margin: EdgeInsets.symmetric(
vertical: 10.0, horizontal: 4.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
color: _current == index
? Colors.deepPurple
: Colors.grey,
),
);
}),
),
],
),
),
),
],
),
),
),
猜猜我只是害怕什么:D
关于flutter - 如何将英雄小部件动画到另一个页面中轮播的第一个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63376126/