前言 :
各位同學(xué)大家好, 瀑布流列表顯示效果相信在坐的同學(xué)中做過原生安卓 和iOS的同學(xué)都有實現(xiàn)過吧斯够。 原生的實現(xiàn)方式網(wǎng)上都很多開源例子甚至是開源庫 ,我就不展開講了。今天我主要給大家介紹下flutter中瀑布流如何實現(xiàn)的 法绵,廢話不多說我們正式開始 秧骑。
效果如圖:
準(zhǔn)備工作 :
安裝flutter環(huán)境 如果只是跑安卓設(shè)備渣淤, win系統(tǒng)就行了均抽。要是同時運行安卓和iOS 就需要mac電腦了 配置環(huán)境變量這邊就不展開講了,大家可以看我之前的文章。
需要用到的三方庫:
flutter_staggered_grid_view:
cached_network_image: ^2.2.0+1
flutter sdk 版本 如圖:
首先請把 這個兩個三方庫
flutter_staggered_grid_view:
cached_network_image: ^2.2.0+1
拷貝到項目的 pubspec.yaml 中 如圖:
然后在控制臺輸入 flutter pub get 命令進行下載以來即可
這邊主要是用到三方庫中的 StaggeredGridView 組件,在flutter原生api的里面提供的lisview 和gridview 并沒有提供瀑布流的實現(xiàn)效果 取具,所以我們用到這個三方庫組件 StaggeredGridView 來實現(xiàn)脖隶。
1、使用StaggeredGridView
大體就兩種方式暇检,一種是傳入List<Widget>另一種是用itemBuilder創(chuàng)建item产阱,默認(rèn)提供了一下幾種方法創(chuàng)建,根據(jù)自己的需要選擇即可块仆。
StaggeredGridView()
StaggeredGridView.builder()
StaggeredGridView.custom()
StaggeredGridView.count()
StaggeredGridView.countBuilder()
StaggeredGridView.extent()
StaggeredGridView.extentBuilder()
這里我們選擇使用countBuilder這種模式
body: new StaggeredGridView.countBuilder(
padding: const EdgeInsets.all(8.0),
crossAxisCount: 4,
itemCount: imgList.length,
itemBuilder: (context, i) {
return itemWidget(i);
},
// staggeredTileBuilder: (index) => new StaggeredTile.fit(2),
staggeredTileBuilder: (int index) =>
new StaggeredTile.count(2, index == 0 ? 2.5 : 3), //
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
),
staggeredTileBuilder則決定每個item的寬高,核心邏輯心墅。
staggeredTileBuilder: (int index) => new StaggeredTile.count(2, index == 0 ? 2.5 : 3),
我這里設(shè)置第一張主軸為2.5其他的為3這樣就形成了一個簡單的瀑布流樣式
具體效果如圖:
具體完整代碼實現(xiàn)如下:
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'full_screenimagepage.dart';
/**
* 創(chuàng)建人:xuqing
* 創(chuàng)建時間:2020年6月26日04:00:19
* 類說明:瀑布流主頁邏輯實現(xiàn)
*
*/
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: '瀑布流'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List imgList = [
"http://yanxuan.nosdn.127.net/65091eebc48899298171c2eb6696fe27.jpg",
"http://yanxuan.nosdn.127.net/8b30eeb17c831eba08b97bdcb4c46a8e.png",
"http://yanxuan.nosdn.127.net/a196b367f23ccfd8205b6da647c62b84.png",
"http://yanxuan.nosdn.127.net/149dfa87a7324e184c5526ead81de9ad.png",
"http://yanxuan.nosdn.127.net/88dc5d80c6f84102f003ecd69c86e1cf.png",
"http://yanxuan.nosdn.127.net/8b9328496990357033d4259fda250679.png",
"http://yanxuan.nosdn.127.net/c39d54c06a71b4b61b6092a0d31f2335.png",
"http://yanxuan.nosdn.127.net/ee92704f3b8323905b51fc647823e6e5.png",
"http://yanxuan.nosdn.127.net/e564410546a11ddceb5a82bfce8da43d.png",
"http://yanxuan.nosdn.127.net/56f4b4753392d27c0c2ccceeb579ed6f.png",
"http://yanxuan.nosdn.127.net/6a54ccc389afb2459b163245bbb2c978.png",
'https://picsum.photos/id/101/548/338',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1569842561051&di=45c181341a1420ca1a9543ca67b89086&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201504%2F17%2F20150417212547_VMvrj.jpeg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1570437233&di=9239dbc3237f1d21955b50e34d76c9d5&imgtype=jpg&er=1&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201508%2F30%2F20150830095308_UAQEi.thumb.700_0.jpeg'
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new StaggeredGridView.countBuilder(
padding: const EdgeInsets.all(8.0),
crossAxisCount: 4,
itemCount: imgList.length,
itemBuilder: (context, i) {
return itemWidget(i);
},
// staggeredTileBuilder: (index) => new StaggeredTile.fit(2),
staggeredTileBuilder: (int index) =>
new StaggeredTile.count(2, index == 0 ? 2.5 : 3), //
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
),
);
}
Widget itemWidget(int index){
String imgPath = imgList[index];
return new Material(
elevation: 8.0,
borderRadius: new BorderRadius.all(
new Radius.circular(8.0),
),
child: new InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) {
return new FullScreenImagePage(imageurl: imgPath);
},
),
);
},
child: new Hero(
tag: imgPath,
child: CachedNetworkImage(
imageUrl: imgPath,
fit: BoxFit.fitWidth,
/* placeholder: (context, url) =>
Image.asset('assets/wallfy.png'),*/
),
),
),
);
}
}
最后在item的點擊事件里面添加了點擊跳轉(zhuǎn)到新開頁面widget顯示所點擊的圖片
點擊核心代碼
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) {
return new FullScreenImagePage(imageurl: imgPath);
},
),
);
},
通過構(gòu)造方法把選中的圖片的url傳到 FullScreenImagePage 類中, 然后在Img.network中傳入即可實現(xiàn)
跳轉(zhuǎn)新頁面核心代碼 :
import 'package:flutter/material.dart';
/**
*
* 創(chuàng)建人:xuqing
* 創(chuàng)建時間:2020年6月26日03:03:05
* 類說明:圖片詳情頁面
*
*/
class FullScreenImagePage extends StatefulWidget {
final String imageurl;
FullScreenImagePage({Key key,this.imageurl}) : super(key: key);
@override
_FullScreenImagePageState createState() {
return _FullScreenImagePageState();
}
}
class _FullScreenImagePageState extends State<FullScreenImagePage> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("圖片詳情頁面"),
centerTitle: true,
),
body:Container(
margin: EdgeInsets.all(20.0),
child: Image.network(widget.imageurl, fit: BoxFit.fitWidth,),
),
);
}
}
最后總結(jié) :
相交于安卓原生來說 flutter提供了很好用很方便的三方庫組件flutter_staggered_grid_view, 來實現(xiàn)就簡單方便很多 也節(jié)省大家的開發(fā)時間和提供開發(fā)效率酿矢。flutter_staggered_grid_view 用法用起來和gridview差別不大,個別特殊屬性大家需要注意 ,當(dāng)然這種瀑布流列表布局也可以自己封裝gridview來實現(xiàn) 有興趣的同學(xué)可以私下研究下怎燥。這里就不過多講了 最后希望我的文章能幫助到各位解決問題 ,以后我還會貢獻更多有用的代碼分享給大家蜜暑。如果覺得文章還不錯 ,麻煩給關(guān)注和star
項目地址:https://github.com/xq19930522/pubuliu