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;
});
},
)
),
),
),
),
);
}
}
