文章目錄
- Flutter PageView元件
-
- 簡述
- 基本屬性
- 簡單使用
- 無限滾動效果
- 輪播圖
Flutter PageView元件
簡述
Flutter中的PageView元件類似于Android中的ViewPage控件,可以實作頁面滑動切換,可以和BottomNavigationBar等配合使用。
基本屬性
scrollDirection:滑動方向。
- Axis.horizontal:水準方向。
- Axis.vertical:垂直方向。
pageSnapping:滑動時是否強制切換頁面,如果為false,不會切換頁面,如果為true,會強制切換頁面。
controller:PageController類型,控制PageView。
- initialPage:預設第幾頁。
- viewportFraction:每頁占用空間。
onPageChanged:PageView滑動監聽。
allowImplicitScrolling:是否預加載下一頁,一般情況下緩存前後兩頁。
簡單使用
class SimplePageViewPage extends StatefulWidget {
const SimplePageViewPage({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _SimplePageViewPageState();
}
}
class _SimplePageViewPageState extends State<SimplePageViewPage> {
@override
Widget build(BuildContext context) {
List<Page> pageList = [];
for (int i = 0; i < Colors.primaries.length; i++) {
pageList.add(Page(title: "$i", color: Colors.primaries[i]));
}
return Scaffold(
appBar: AppBar(
title: const Text("PageView簡單使用"),
),
body: PageView(
scrollDirection: Axis.horizontal,
allowImplicitScrolling: true,
pageSnapping: true,
children: pageList,
controller: PageController(viewportFraction: 0.8, initialPage: 1),
onPageChanged: (index) {
print("onPageChanged $index");
},
),
);
}
}
class Page extends StatelessWidget {
final String title;
final Color color;
const Page({Key? key, required this.title, required this.color}) : super(key: key);
@override
Widget build(BuildContext context) {
print("build $title");
return Container(
color: color,
alignment: Alignment.center,
child: Text(title, textScaleFactor: 2),
);
}
}
無限滾動效果
class XPageViewPage extends StatelessWidget {
const XPageViewPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
List<Widget> pageList = const [
Page(title: "1", color: Colors.red),
Page(title: "2", color: Colors.green),
Page(title: "3", color: Colors.blue),
];
return Scaffold(
appBar: AppBar(
title: const Text("PageView無限滾動"),
),
body: PageView.builder(
itemCount: 10000,
itemBuilder: (BuildContext context, int index) {
return pageList[index % pageList.length];
},
),
);
}
}
輪播圖
class BannerPage extends StatefulWidget {
const BannerPage({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _BannerPageState();
}
}
class _BannerPageState extends State<BannerPage> {
List<String> titles = ["One", "Two", "Three"];
List<Color> colors = [Colors.red, Colors.green, Colors.blue];
int currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("輪播圖")),
body: Center(
child: SizedBox(
height: 250,
child: Stack(
children: [
_buildItem(),
_buildPoint(),
],
),
),
),
);
}
_buildItem() {
return PageView.builder(
itemCount: 1000,
itemBuilder: (BuildContext context, int index) {
int realIndex = index % titles.length;
Color color = colors[realIndex];
String title = titles[realIndex];
return Container(
color: color,
alignment: Alignment.center,
child: Text(
title,
style: const TextStyle(color: Colors.white),
),
);
},
onPageChanged: (int index) {
setState(() {
currentIndex = index % titles.length;
});
},
);
}
_buildPoint() {
return Positioned(
bottom: 10,
left: 0,
right: 0,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
titles.length,
(index) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 3),
width: 10,
height: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: currentIndex == index
? Colors.red.shade900
: Colors.grey.shade50,
),
);
},
),
),
);
}
}