好久沒有自學flutter,有點落下,現在有空就抓緊補上,如標題所示,這篇博文是實現輪播圖Swiper、GridView的組合佈局及各自的點擊事件,最後是將它們抽出方法來,而不是全部寫在build裏面,不然代碼看起來不舒服而且不易維護。我自己摸索了一個上午,一邊調試一邊查閱資料,最後實現後,整理好代碼就寫這篇博文了。效果圖如下所示(湊齊六宮格,重點後面一排):
說明:代碼出現的自定義字體、使用本地圖片,你可以不用它(圖片換成網絡的),如果你想用可是又不會用,可以看前面的flutter學習二(裏面有涉及怎麼使用本地圖片)、flutter學習四(字體)。
一. 輪播圖:
1. 在看代碼之前,先添加swiper包,在pubspec.yaml裏面添加如下圖(按照提示依次操作):
2. 操作1後可以看如下代碼了,關於用到的屬性解釋,我是根據自己的理解來備註的,網上有更多的屬性及詳細的說明,你可以網上查找,我這裏就詳細說了:
注:代碼必須寫在Widget build(BuildContext context)前面,getDialog( )是顯示dialog的一個方法,後面會給出相關代碼。
//本地圖片,也可以使用網絡圖片
static List imageList = [
'images/lake.jpg',
'images/lake.jpg',
'images/lake.jpg'
];
Container(
//輪播圖的高度
height: 120,
//輪播圖,還有其它的屬性,這裏不一一介紹了
child: Swiper(
//有多少個
itemCount: imageList.length,
//是否自動滾動
autoplay: true,
//滾動的放心,左右、上下(默認左右)
scrollDirection: Axis.horizontal,
//用戶滑動輪播圖時是否停止自動播放
autoplayDisableOnInteraction: true,
itemBuilder: (BuildContext context, int index) {
return Image.asset(
//顯示imageList裏面的圖片、imageList是網絡圖片時用Image.network
imageList[index],
fit: BoxFit.fill, //填充方式
);
},
//輪播改變時調用的(用戶操作或者自動輪播)
onIndexChanged: (index) {
//相應的操作,一般也不操作
},
//點擊某個輪播圖
onTap: (index) {
showDialog(
context: context1,
barrierDismissible: true, //點擊彈窗外部是否消失
child: getDialog("您點擊了第:$index個輪播圖"), //dialog顯示點擊的內容
);
},
//顯示指示器,SwiperPagination()是默認,可以在裏面修改位置、距離、樣式
pagination: SwiperPagination(
alignment: Alignment.bottomCenter, //指示器的位置
margin: const EdgeInsets.only(bottom: 10), //瑜邊框的距離
builder: SwiperPagination.dots, //指示器的樣式:dots點、fraction數字
),
),
);
二. GridView的顯示、點擊事件及顯示dialog:
注:代碼必須寫在Widget build(BuildContext context)前面
//顯示的數據
static List chainList = ['武漢', '加油!', '中國', '加油!', '我們', '必勝!'];
Container(
child: GridView.count(
shrinkWrap: true,
//解決listView嵌套GridView不能滾動問題
physics: new NeverScrollableScrollPhysics(),
//水平之間的間距
crossAxisSpacing: 10.0,
//垂直之間的間距
mainAxisSpacing: 30.0,
//GridView內邊距,all四個方向
padding: EdgeInsets.all(10.0),
//一行顯示多少個Widget
crossAxisCount: 1,
//Widget寬高比例
childAspectRatio: 2.0,
//數據
children: getGridList(),
),
);
//獲取GridView顯示的數據,及設置子item的樣式
static List<Widget> getGridList() {
return chainList.map((item) => getItemContainer(item)).toList();
}
//每個GridView裏面的item設置
static Widget getItemContainer(String item) {
return new GestureDetector(
//點擊事件 onTap輕按
onTap: () {
showDialog(
context: context1,
barrierDismissible: true, //點擊彈窗外部是否消失
child: getDialog(item), //dialog顯示點擊的內容
);
},
child: new Container(
height: 80,
margin: EdgeInsets.only(bottom: 5),
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.red),
child: Text(
item,
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
);
}
三. 在build裏面將Swiper、GridView進行組合,更多的摸索的時間花在這裏了,裏面涉及到ListView嵌套GridView:
注:這樣子組合,把對應分wigdet進行封裝,而不是全部佈局寫在body: Center裏面,是不是簡潔好看多了,而且也方便管理
new ListView(
shrinkWrap: true,
children: <Widget>[
swiperSection,
gridSection,
],
),
四. 完整代碼:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
class HomeScreen extends StatelessWidget {
//自定義字體
final textStyle = const TextStyle(
fontFamily: 'Chu',
color: Colors.red,
fontSize: 20,
);
//用於路由(就是界面的跳轉),當跳轉的事件沒有寫在build裏面時用到(我這裏抽到了loginButton裏面)
static BuildContext context1;
//本地圖片,也可以使用網絡圖片
static List imageList = [
'images/lake.jpg',
'images/lake.jpg',
'images/lake.jpg'
];
static List chainList = ['武漢', '加油!', '中國', '加油!', '我們', '必勝!'];
//輪播圖控件,寫在build的前面,Container創建矩形視覺元素,可對元素進行修飾eg:背景色、邊框、邊距、填充等
static Widget swiperSection = new Container(
//輪播圖的高度
height: 120,
//輪播圖,還有其它的屬性,這裏不一一介紹了
child: Swiper(
//有多少個
itemCount: imageList.length,
//是否自動滾動
autoplay: true,
//滾動的放心,左右、上下(默認左右)
scrollDirection: Axis.horizontal,
//用戶滑動輪播圖時是否停止自動播放
autoplayDisableOnInteraction: true,
itemBuilder: (BuildContext context, int index) {
return Image.asset(
//顯示imageList裏面的圖片、imageList是網絡圖片時用Image.network
imageList[index],
fit: BoxFit.fill, //填充方式
);
},
//輪播改變時調用的(用戶操作或者自動輪播)
onIndexChanged: (index) {
//相應的操作,一般也不操作
},
//點擊某個輪播圖
onTap: (index) {
showDialog(
context: context1,
barrierDismissible: true, //點擊彈窗外部是否消失
child: getDialog("您點擊了第:$index個輪播圖"), //dialog顯示點擊的內容
);
},
//顯示指示器,SwiperPagination()是默認,可以在裏面修改位置、距離、樣式
pagination: SwiperPagination(
alignment: Alignment.bottomCenter, //指示器的位置
margin: const EdgeInsets.only(bottom: 10), //瑜邊框的距離
builder: SwiperPagination.dots, //指示器的樣式:dots點、fraction數字
),
),
);
//GridView控件
static Widget gridSection = new Container(
child: GridView.count(
shrinkWrap: true,
//解決listView嵌套GridView不能滾動問題
physics: new NeverScrollableScrollPhysics(),
//水平之間的間距
crossAxisSpacing: 10.0,
//垂直之間的間距
mainAxisSpacing: 30.0,
//GridView內邊距,all四個方向
padding: EdgeInsets.all(10.0),
//一行顯示多少個Widget
crossAxisCount: 1,
//Widget寬高比例
childAspectRatio: 2.0,
//數據
children: getGridList(),
),
);
//獲取GridView顯示的數據,及設置子item的樣式
static List<Widget> getGridList() {
return chainList.map((item) => getItemContainer(item)).toList();
}
//每個GridView裏面的item設置
static Widget getItemContainer(String item) {
return new GestureDetector(
//點擊事件 onTap輕按
onTap: () {
showDialog(
context: context1,
barrierDismissible: true, //點擊彈窗外部是否消失
child: getDialog(item), //dialog顯示點擊的內容
);
},
child: new Container(
height: 80,
margin: EdgeInsets.only(bottom: 5),
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.red),
child: Text(
item,
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
);
}
//顯示點擊事件
static Widget getDialog(String item) {
return new AlertDialog(
title: new Text(
//標題
'提示',
style: new TextStyle(color: Colors.red[300], fontSize: 18),
),
content: new Text(item), //提示語
actions: <Widget>[
new FlatButton(
//一個扁平的Material按鈕
onPressed: () {
Navigator.of(context1).pop(); //彈窗消失
},
child: Text('取消')),
new FlatButton(
//對話框按鈕
onPressed: () {
Navigator.of(context1).pop(); //彈窗消失
},
child: Text('確定')),
],
);
}
Widget build(BuildContext context) {
context1 = context;
return new Scaffold(
appBar: new AppBar(
title: new Text(
'首頁',
style: textStyle,
),
),
body: new ListView(
shrinkWrap: true,
children: <Widget>[
swiperSection,
gridSection,//涉及listView嵌套GridView
],
),
);
}
}
到此完成了,有更好的建議評論區見!