界面設計
圖片輪播效果實現一般都用在相冊之中,所以我們的主界面應該是一個相冊App的樣式,假設我們的相冊是這個樣子的,如下圖所示(同樣也是最後代碼的實現效果):
其中,它有一個標題欄,上面僅僅寫了APP的名字叫:lyj圖片瀏覽器,接着下面是一個背景圖,圖中有一個我的相冊的文字提示,接着下面就是我們的網格樣式的所有圖片,那麼我們應該使用哪些組件呢?
肯定會有網格組件GridView,其次爲了效果好看我們使用了層疊組件Stack,所以這裏我們有了兩個滑動組件,那麼就需要使用CustonScrollView,而GridView也需要採用SliverGrid組件,App所有的界面控件弄清楚了,下面就該編寫代碼了。
代碼設計
首先,我們需要認識一個新的可以伸縮的頭部組件SliverPersistentHeader,藉着新項目認識一下其他組件還是有好處的,它有點類似與SliverAppBar,也是可以根據滾動的距離縮小高度。並且這個組件SliverPersistentHeader也有一個抽象類SliverPersistentHeaderDelegate,這裏我們需要實現該接口,代碼如下:
抽象類SliverPersistentHeaderDelegate實現
class MySliverPersistentHeaderDelegate implements SliverPersistentHeaderDelegate{
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return Stack(//類似於Java開發Android中FrameLayout控件
fit: StackFit.expand,//大小與父組件一樣大
children: <Widget>[
Image.asset(
'assets/timg.jpg',
fit: BoxFit.cover,//充滿容器,可能會被截斷。
),
Container(
decoration: BoxDecoration(//裝飾器
gradient: LinearGradient(//線性漸變
colors: [
Colors.transparent,
Colors.black54
],
stops: [0.5, 1.0],//漸變的取值
//從上到下漸變
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
tileMode: TileMode.repeated,
),
),
),
Positioned(
//離左右下的邊距
left: 16.0,
right: 16.0,
bottom: 16.0,
child: Text(
'我的相冊',
style: TextStyle(fontSize: 28.0, color: Colors.white),
),
),
],
);
}
//構造函數傳入:maxExtent表示header完全展開時的高度,minExtent表示header在收起時的最小高度
MySliverPersistentHeaderDelegate({
this.minExtent,
this.maxExtent,
});
double maxExtent;
double minExtent;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
return true;
}
@override
// TODO: implement snapConfiguration
FloatingHeaderSnapConfiguration get snapConfiguration => null;
@override
// TODO: implement stretchConfiguration
OverScrollHeaderStretchConfiguration get stretchConfiguration => null;
}
MyHomePage
上面代碼註釋已經非常多了,這裏就不在贅述了,接着就是我們主界面MyHomePage的實現,具體的代碼如下:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'lyj圖片瀏覽器',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'lyj圖片瀏覽器'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final int rowCount = 3; // 每行顯示的圖片數
final List<String> imagesList = [//用到的圖片
'assets/1.jpg',
'assets/2.jpg',
'assets/3.jpg',
'assets/4.jpg',
'assets/5.jpg',
'assets/6.jpg',
'assets/7.jpg',
'assets/8.jpg',
'assets/9.jpg',
];
Widget _scrollView(BuildContext context){
return Container(
child: CustomScrollView(
slivers: <Widget>[
SliverPersistentHeader(
pinned: true,//是否可以展開
delegate: MySliverPersistentHeaderDelegate(minExtent: 100,maxExtent: 200),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: MediaQuery.of(context).size.width / rowCount,//屏幕寬度除每行個數,單個子Widget的水平最大寬度
mainAxisSpacing: 0.0,//水平單個子Widget之間間距
crossAxisSpacing: 0.0,//垂直單個子Widget之間間距
childAspectRatio: 9.0/16,//寬高比
),
delegate: SliverChildBuilderDelegate((BuildContext context,int index){
return Container(
alignment: Alignment.center,
padding: EdgeInsets.only(top: 2,left: 2,bottom: 2,right: 2),//各填充2個空白像素
child: Image.asset(imagesList[index%imagesList.length]),
);
},childCount: imagesList.length*3),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: new Text(widget.title),),
body: _scrollView(context),
);
}
}
代碼很簡單,與前面博文講解多元素組件的GridView一樣實現的,當然這裏是把body中的組件全提取出來了,這樣看起來簡介一些。當然那些圖片需要配置到pubspec.yaml文件中:
flutter:
assets:
- assets/1.jpg
- assets/2.jpg
- assets/3.jpg
- assets/4.jpg
- assets/5.jpg
- assets/6.jpg
- assets/7.jpg
- assets/8.jpg
- assets/9.jpg
- assets/timg.jpg
GitHub代碼下載地址:點擊下載