Flutter 九宫格及Hero动画

1.数据资源类
class LXPhotosData {
         final String imgUrl;
         LXPhotosData(this.imgUrl);
}

2.定义一个继承StatefulWidget的外部调用类,九宫格界面,里面定义了几个常量,用来设置,具体请看代码,

 

通过FadeTransition 实现了淡入淡出效果

 

class LXPhotosView extends StatefulWidget {

//数据资源
final List<LXPhotosData> list;
//主轴间距
final double mainAxisPaddingSize;
//交叉轴间距
final double crossAxisPaddingSize;
// 圆角大小(默认没有圆角)
final double radiusSize;
//交叉轴个数 (默认值 根据九宫格个数决定)
final int currentCrossAxisCount;
//背景颜色
final Color bgColor;

///构造方法
LXPhotosView({
Key key,
@required this.list,
this.mainAxisPaddingSize = 5,
this.crossAxisPaddingSize = 5,
this.radiusSize = 0.0,
this.bgColor = Colors.white,
int currentCrossAxisCount
}) : this.currentCrossAxisCount = currentCrossAxisCount ?? (list.length == 4 ? 2 : 3),
super(key: key);


@override
_PhotosViewState createState() => _PhotosViewState();

}

class _PhotosViewState extends State<LXPhotosView> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Center(
child: Container(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: this.widget.currentCrossAxisCount,
crossAxisSpacing: this.widget.crossAxisPaddingSize,
mainAxisSpacing: this.widget.mainAxisPaddingSize,
),
itemBuilder: (BuildContext context, int index){
return GestureDetector(
child: Hero(
tag: widget.list[index].imgUrl,
child: Container(
color: widget.bgColor,
child: ClipRRect(
borderRadius: BorderRadius.circular(widget.radiusSize),
child: Image(
image: NetworkImage(widget.list[index].imgUrl),
fit: BoxFit.fitWidth,

),
),
),
),
onTap: () {
Navigator.of(context).push(PageRouteBuilder(
pageBuilder: (context,animation, secondaryAnimation) {
return FadeTransition(
opacity: animation,
child: LXScrollPhotosView(currentIndex: index,currentList: widget.list,)
);
}
)
);
} ,
);
},
itemCount: widget.list.length,
),
),
);
}
}

3.跳转界面界面,存在Hero动画,注意细节九宫格tag要保持与详情界面保持一致才能实现此效果,
用PageView做多张图片浏览处理,最好用builder命名构造创建

class LXScrollPhotosView extends StatefulWidget {

//点击的当前索引
final int currentIndex;
//当前数据集合
final List<LXPhotosData> currentList;

LXScrollPhotosView({
Key key,
@required this.currentIndex,
@required this.currentList,
}) : super(key: key);

@override
_LXScrollPhotosViewState createState() => _LXScrollPhotosViewState();

}

class _LXScrollPhotosViewState extends State<LXScrollPhotosView> {

int _indexPage;
PageController _pageController;

@override
void initState() {
super.initState();
_indexPage = widget.currentIndex;
_pageController = PageController(
initialPage: _indexPage,
viewportFraction: 1.06
);
}

@override
void dispose() {
_pageController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Hero(
tag: widget.currentList[_indexPage].imgUrl,
child: Container(
child: PageView.builder(
itemBuilder: (BuildContext context, int index){
return Container(
padding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.03),
child: Image(
image: NetworkImage(widget.currentList[index].imgUrl),
fit: BoxFit.fitWidth,
),
);
},
controller: _pageController,
scrollDirection: Axis.horizontal,
itemCount: widget.currentList.length,
onPageChanged: (index){
setState(() {
_indexPage = index;
});
},
)
),
),
),
),
);
}
}


posted @ 2020-03-29 13:37  小鱼的市场  阅读(1125)  评论(0编辑  收藏  举报