Dialog弹窗,用于显示信息、提示用户或获取用户输入,PageView则是一个可滑动的页面视图,用于展示多页面切换效果。
1 Dialog弹出窗口
- AlertDialog(弹窗提示信息)、SimpleDialog(弹窗选择信息)、showModalBottomSheet(底部弹出窗口)。
- 下载包:到pubspec.yaml的
dependencies
中加入fluttertoast: ^8.2.4
,保存后点Pub get
下载。 - 如果报错,参看:uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library。
1-1 内置的Dialog
# myflutter(项目名)目录结构如下
- pages/
- tabs/
- user.dart
- home.dart
- setting.dart
- category.dart
- tabs.dart
- dialog.dart
- routes/
- routes.dart
- main.dart
(1) user.dart
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("用户信息"),
);
}
}
(2) tabs.dart
import './tabs/user.dart';
import './tabs/home.dart';
import './tabs/setting.dart';
import './tabs/category.dart';
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({Key? key, this.index=0}) : super(key: key);
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(), CategoryPage(), SettingPage(), UserPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("内置的Dialog")),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 选中的颜色
fixedColor: Colors.red,
// 配置底部菜单大小
iconSize: 40,
// 4个以上菜单需配置此项
type: BottomNavigationBarType.fixed,
// 默认选中分类(第二个)
// currentIndex: 1,
currentIndex: _currentIndex,
onTap: (index){
// 获取点击的索引值
// print(index);
// 注意调用setState
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon:Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon:Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon:Icon(Icons.settings),
label: "设置",
),
// 没有type菜单图标会被挤掉
BottomNavigationBarItem(
icon:Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
(3) main.dart
import './routes/routes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// 去掉右上角debug图标
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// 全局配置主题
appBarTheme: const AppBarTheme(
// 主题标题全部居中显示
centerTitle: true
),
),
// home: const Tabs(),
// 初始化路由
initialRoute: "/",
// 固定写法,配置onGenerateRoute
onGenerateRoute: onGenerateRoute,
);
}
}
(4) home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/dialog");
},
child: const Text("Dialog演示"),
),
],
),
);
}
}
(5) dialog.dart
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class DialogPage extends StatefulWidget {
const DialogPage({Key? key}) : super(key: key);
@override
State<DialogPage> createState() => _DialogPageState();
}
class _DialogPageState extends State<DialogPage> {
void _alertDialog() async {
// print("_alertDialog");
var result = await showDialog(context: context, builder: (context) {
return AlertDialog(
title: const Text("提示信息!"),
content: const Text("您确定要删除吗?"),
actions: [
TextButton(onPressed: () {
print("OK");
// 点击按钮关闭窗口
Navigator.of(context).pop("OK");
}, child: const Text("确定")),
TextButton(onPressed: () {
print("Cancel");
// 外层result打印信息
Navigator.of(context).pop("Cancel");
}, child: const Text("取消")),
],
);
}); print(result);
}
void _simpleDialog() async {
// barrierDismissible
// print("_simpleDialog");
// 点灰色背景,弹窗不消失
var result = await showDialog(
barrierDismissible: false, context: context, builder: (context) {
return SimpleDialog(
title: const Text("请选择语言:"),
children: [
SimpleDialogOption(
// Navigator.of().pop()方法一
onPressed: () {
print("汉语");
Navigator.of(context).pop("汉语");
}, child: const Text("汉语"),
), const Divider(),
SimpleDialogOption(
// Navigator.pop()方法二
onPressed: () {
print("英语");
Navigator.pop(context, "英语");
}, child: const Text("英语"),
), const Divider(),
SimpleDialogOption(
// pop不传第二个参数值返回null
onPressed: () {
print("日语");
Navigator.pop(context, "日语");
}, child: const Text("日语"),
), const Divider(),
],
);
},
); print("----"); print(result);
}
void _modelBottomSheet() async {
// print("_modelBottomSheet");
var result = await showModalBottomSheet(context: context, builder: (context) {
return SizedBox(
height: 200,
child: Column(
children: [
ListTile(
title: const Text("分享"),
onTap: () {print("分享"); Navigator.pop(context, "分享");},
), const Divider(),
ListTile(
title: const Text("收藏"),
onTap: () {print("收藏"); Navigator.pop(context, "收藏");},
), const Divider(),
ListTile(
title: const Text("取消"),
onTap: () {print("取消"); Navigator.pop(context, "取消");},
),
],
),
);
}); print("****"); print(result);
}
void _toast() {
// print("_toast");
// 使用该功能,需要重新flutter run
Fluttertoast.showToast(
msg: "提示信息",
// 值针对Android平台,1秒消失
toastLength: Toast.LENGTH_SHORT,
// 5秒消失
// toastLength: Toast.LENGTH_LONG,
// 调整方位
gravity: ToastGravity.TOP,
// 提示时间,针对iOS和Web
timeInSecForIosWeb: 1,
// 背景颜色
backgroundColor: Colors.black,
// 文本颜色
textColor: Colors.white,
// 文本字体大小
fontSize: 16.0,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Dialog")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _alertDialog,
child: const Text("弹窗提示信息:AlertDialog"),
), const SizedBox(height: 20),
ElevatedButton(
onPressed: _simpleDialog,
child: const Text("弹窗选择信息:SimpleDialog"),
), const SizedBox(height: 20),
ElevatedButton(
onPressed: _modelBottomSheet,
child: const Text("底部弹窗:showModalBottomSheet"),
), const SizedBox(height: 20),
ElevatedButton(
onPressed: _toast, child: const Text("Toast"),
),
],
),
),
);
}
}
(6) routes.dart
import '../pages/tabs.dart';
import '../pages/dialog.dart';
// 配置iOS风格的路由,引入库
import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// 定义一个Map类型的路由
Map routes = {
"/": (context) => const Tabs(),
"/dialog": (context) => const DialogPage(),
};
// 配置onGenerateRoute,固定写法,该方法相当于一个中间件,可以做权限判断
// ignore: prefer_function_declarations_over_variables
var onGenerateRoute = (RouteSettings settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
// final Route route = MaterialPageRoute(
// 替换MaterialPageRoute
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(
context, arguments: settings.arguments
)
);
return route;
} else {
// final Route route = MaterialPageRoute(
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(context)
);
return route;
}
}
return null;
};
(7) setting.dart
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("系统设置"),
);
}
}
(8) category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({Key? key}) : super(key: key);
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类页面"),
);
}
}
1-2 自定义Dialog
- 自定义Dialog需继承Dialog类,它所提供的child用于编写视图界面,可能达不到想要的效果。
- 因为默认的Dialog背景框是满屏展示的,如果想要完全自定义界面,就必须得重写build函数。
# myflutter(项目名)目录结构如下
- pages/
- tabs/
- user.dart
- home.dart
- setting.dart
- category.dart
- tabs.dart
- dialog.dart
- routes/
- routes.dart
- widget/
- myDialog.dart
- main.dart
(1) user.dart
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("用户信息"),
);
}
}
(2) tabs.dart
import './tabs/user.dart';
import './tabs/home.dart';
import './tabs/setting.dart';
import './tabs/category.dart';
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({Key? key, this.index=0}) : super(key: key);
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(), CategoryPage(), SettingPage(), UserPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("自定义Dialog")),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 选中的颜色
fixedColor: Colors.red,
// 配置底部菜单大小
iconSize: 40,
// 4个以上菜单需配置此项
type: BottomNavigationBarType.fixed,
// 默认选中分类(第二个)
// currentIndex: 1,
currentIndex: _currentIndex,
onTap: (index){
// 获取点击的索引值
// print(index);
// 注意调用setState
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon:Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon:Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon:Icon(Icons.settings),
label: "设置",
),
// 没有type菜单图标会被挤掉
BottomNavigationBarItem(
icon:Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
(3) main.dart
import './routes/routes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// 去掉右上角debug图标
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// 全局配置主题
appBarTheme: const AppBarTheme(
// 主题标题全部居中显示
centerTitle: true
),
),
// home: const Tabs(),
// 初始化路由
initialRoute: "/",
// 固定写法,配置onGenerateRoute
onGenerateRoute: onGenerateRoute,
);
}
}
(4) home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/dialog");
},
child: const Text("Dialog演示"),
),
],
),
);
}
}
(5) dialog.dart
import '../widget/myDialog.dart';
import 'package:flutter/material.dart';
class DialogPage extends StatefulWidget {
const DialogPage({Key? key}) : super(key: key);
@override
State<DialogPage> createState() => _DialogPageState();
}
class _DialogPageState extends State<DialogPage> {
void _myDialog() async {
// print("_myDialog");
var result = await showDialog(
// 点灰色背景,弹窗不消失
barrierDismissible: false,
context: context, builder: (context) {
return MyDialog(
title: "提示!",
content:
"采采流水,蓬蓬远春。窈窕深谷,时见美人。\n"
"碧桃满树,风日水滨。柳阴路曲,流莺比邻。\n"
"乘之愈往,识之愈真。如将不尽,与古为新。",
opTap: () {
print("关闭");
Navigator.of(context).pop("关闭按钮事件");
},
);
});
print(result);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Dialog")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
// 不加括号表示注册方法
onPressed: _myDialog,
// 加括号表示调用方法
// onPressed: _myDialog(),
child: const Text("自定义Dialog"),
),
],
),
),
);
}
}
(6) routes.dart
import '../pages/tabs.dart';
import '../pages/dialog.dart';
// 配置iOS风格的路由,引入库
import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// 定义一个Map类型的路由
Map routes = {
"/": (context) => const Tabs(),
"/dialog": (context) => const DialogPage(),
};
// 配置onGenerateRoute,固定写法,该方法相当于一个中间件,可以做权限判断
// ignore: prefer_function_declarations_over_variables
var onGenerateRoute = (RouteSettings settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
// final Route route = MaterialPageRoute(
// 替换MaterialPageRoute
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(
context, arguments: settings.arguments
)
);
return route;
} else {
// final Route route = MaterialPageRoute(
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(context)
);
return route;
}
}
return null;
};
(7) setting.dart
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("系统设置"),
);
}
}
(8) category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({Key? key}) : super(key: key);
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类页面"),
);
}
}
(9) myDialog.dart
import 'package:flutter/material.dart';
// 继承Dialog类
class MyDialog extends Dialog {
// 外部传值设置
final String title;
final String content;
final Function()? opTap;
const MyDialog({
Key? key, required this.title, required this.content, required this.opTap
}) : super(key: key);
@override
// 实现build方法
Widget build(BuildContext context) {
return Material(
// 设置背景透明
type: MaterialType.transparency,
// 用于包裹组件,否则全屏展示
child: Center(
child: Container(
height: 200, width: 300, color: Colors.white,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(10),
child: Stack(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(title, style: const TextStyle(fontSize: 18)),
),
Align(
alignment: Alignment.centerRight,
// child: Icon(Icons.close),
child: InkWell(
child: const Icon(Icons.close),
// onTap: () {print("close"); Navigator.pop(context);},
onTap: opTap,
),
),
],
),
), const Divider(),
Container(
padding: const EdgeInsets.all(20),
width: double.infinity,
child: Text(content, style: const TextStyle(fontSize: 13)),
),
],
),
),
),
);
}
}
2 PageView的使用
- Flutter中的轮动图以及上下滑页切换视频功能等,都可以通过PageView实现。
- 常见属性
- children(配置子元素)、scrollDirection(Axis.horizonta水平方向,Axis.vertical垂直方向)。
- onPageChanged(page改变的时候触发)、allowImpLicitScrolling(缓存当前页面的前后两页)。
# myflutter(项目名)目录结构如下
- pages/
- tabs/
- user.dart
- home.dart
- setting.dart
- category.dart
- tabs.dart
- pageView.dart
- routes/
- routes.dart
- main.dart
2-1 user.dart
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("用户信息"),
);
}
}
2-2 tabs.dart
import './tabs/user.dart';
import './tabs/home.dart';
import './tabs/setting.dart';
import './tabs/category.dart';
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({Key? key, this.index=0}) : super(key: key);
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(), CategoryPage(), SettingPage(), UserPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("PageView的使用")),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 选中的颜色
fixedColor: Colors.red,
// 配置底部菜单大小
iconSize: 40,
// 4个以上菜单需配置此项
type: BottomNavigationBarType.fixed,
// 默认选中分类(第二个)
// currentIndex: 1,
currentIndex: _currentIndex,
onTap: (index){
// 获取点击的索引值
// print(index);
// 注意调用setState
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon:Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon:Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon:Icon(Icons.settings),
label: "设置",
),
// 没有type菜单图标会被挤掉
BottomNavigationBarItem(
icon:Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
2-3 main.dart
import './routes/routes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// 去掉右上角debug图标
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// 全局配置主题
appBarTheme: const AppBarTheme(
// 主题标题全部居中显示
centerTitle: true
),
),
// home: const Tabs(),
// 初始化路由
initialRoute: "/",
// 固定写法,配置onGenerateRoute
onGenerateRoute: onGenerateRoute,
);
}
}
2-4 home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/pageView");
},
child: const Text("PageView演示"),
),
],
),
);
}
}
2-5 routes.dart
import '../pages/tabs.dart';
import '../pages/pageView.dart';
// 配置iOS风格的路由,引入库
import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// 定义一个Map类型的路由
Map routes = {
"/": (context) => const Tabs(),
"/pageView": (context) => const PageViewPage(),
};
// 配置onGenerateRoute,固定写法,该方法相当于一个中间件,可以做权限判断
// ignore: prefer_function_declarations_over_variables
var onGenerateRoute = (RouteSettings settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
// final Route route = MaterialPageRoute(
// 替换MaterialPageRoute
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(
context, arguments: settings.arguments
)
);
return route;
} else {
// final Route route = MaterialPageRoute(
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(context)
);
return route;
}
}
return null;
};
2-6 setting.dart
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("系统设置"),
);
}
}
2-7 category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({Key? key}) : super(key: key);
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类页面"),
);
}
}
2-8 pageView.dart
import 'package:flutter/material.dart';
class PageViewPage extends StatefulWidget {
const PageViewPage({Key? key}) : super(key: key);
@override
State<PageViewPage> createState() => _PageViewPageState();
}
class _PageViewPageState extends State<PageViewPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("屏幕标题")),
body: PageView(
// 配置PageView垂直滑动,默认滑动方向是水平滑动
scrollDirection: Axis.vertical,
children: [
Center(
child: Text("第1屏", style: Theme.of(context).textTheme.headline1),
),
Center(
child: Text("第2屏", style: Theme.of(context).textTheme.headline1),
),
Center(
child: Text("第3屏", style: Theme.of(context).textTheme.headline1),
),
Center(
child: Text("第4屏", style: Theme.of(context).textTheme.headline1),
),
Center(
child: Text("第5屏", style: Theme.of(context).textTheme.headline1),
),
Center(
child: Text("第6屏", style: Theme.of(context).textTheme.headline1),
),
Center(
child: Text("第7屏", style: Theme.of(context).textTheme.headline1),
),
],
),
);
}
}
3 PageView.builder
# myflutter(项目名)目录结构如下
- pages/
- tabs/
- user.dart
- home.dart
- setting.dart
- category.dart
- tabs.dart
- pageViewBuilder.dart
- routes/
- routes.dart
- main.dart
3-1 user.dart
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("用户信息"),
);
}
}
3-2 tabs.dart
import './tabs/user.dart';
import './tabs/home.dart';
import './tabs/setting.dart';
import './tabs/category.dart';
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({Key? key, this.index=0}) : super(key: key);
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(), CategoryPage(), SettingPage(), UserPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("PageView.builder")),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 选中的颜色
fixedColor: Colors.red,
// 配置底部菜单大小
iconSize: 40,
// 4个以上菜单需配置此项
type: BottomNavigationBarType.fixed,
// 默认选中分类(第二个)
// currentIndex: 1,
currentIndex: _currentIndex,
onTap: (index){
// 获取点击的索引值
// print(index);
// 注意调用setState
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon:Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon:Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon:Icon(Icons.settings),
label: "设置",
),
// 没有type菜单图标会被挤掉
BottomNavigationBarItem(
icon:Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
3-3 main.dart
import './routes/routes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// 去掉右上角debug图标
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// 全局配置主题
appBarTheme: const AppBarTheme(
// 主题标题全部居中显示
centerTitle: true
),
),
// home: const Tabs(),
// 初始化路由
initialRoute: "/",
// 固定写法,配置onGenerateRoute
onGenerateRoute: onGenerateRoute,
);
}
}
3-4 home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/pageViewBuilder");
},
child: const Text("PageViewBuilder演示"),
),
],
),
);
}
}
3-5 routes.dart
import '../pages/tabs.dart';
import '../pages/pageViewBuilder.dart';
// 配置iOS风格的路由,引入库
import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// 定义一个Map类型的路由
Map routes = {
"/": (context) => const Tabs(),
"/pageViewBuilder": (context) => const PageViewBuilderPage(),
};
// 配置onGenerateRoute,固定写法,该方法相当于一个中间件,可以做权限判断
// ignore: prefer_function_declarations_over_variables
var onGenerateRoute = (RouteSettings settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
// final Route route = MaterialPageRoute(
// 替换MaterialPageRoute
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(
context, arguments: settings.arguments
)
);
return route;
} else {
// final Route route = MaterialPageRoute(
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(context)
);
return route;
}
}
return null;
};
3-6 setting.dart
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("系统设置"),
);
}
}
3-7 category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({Key? key}) : super(key: key);
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类页面"),
);
}
}
3-8 pageViewBuilder.dart
import 'package:flutter/material.dart';
class PageViewBuilderPage extends StatefulWidget {
const PageViewBuilderPage({Key? key}) : super(key: key);
@override
State<PageViewBuilderPage> createState() => _PageViewBuilderPageState();
}
class _PageViewBuilderPageState extends State<PageViewBuilderPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("屏幕标题")),
body: PageView.builder(
// 垂直
scrollDirection: Axis.vertical,
itemCount: 10,
itemBuilder: (context, index) {
return Center(
child: Text("第${index+1}层", style: Theme.of(context).textTheme.headline1),
);
},
),
);
}
}
4 实现上拉无限加载
# myflutter(项目名)目录结构如下
- pages/
- tabs/
- user.dart
- home.dart
- setting.dart
- category.dart
- tabs.dart
- pageViewFullPage.dart
- routes/
- routes.dart
- main.dart
4-1 user.dart
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("用户信息"),
);
}
}
4-2 tabs.dart
import './tabs/user.dart';
import './tabs/home.dart';
import './tabs/setting.dart';
import './tabs/category.dart';
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({Key? key, this.index=0}) : super(key: key);
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(), CategoryPage(), SettingPage(), UserPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("实现上拉无限加载")),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 选中的颜色
fixedColor: Colors.red,
// 配置底部菜单大小
iconSize: 40,
// 4个以上菜单需配置此项
type: BottomNavigationBarType.fixed,
// 默认选中分类(第二个)
// currentIndex: 1,
currentIndex: _currentIndex,
onTap: (index){
// 获取点击的索引值
// print(index);
// 注意调用setState
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon:Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon:Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon:Icon(Icons.settings),
label: "设置",
),
// 没有type菜单图标会被挤掉
BottomNavigationBarItem(
icon:Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
4-3 main.dart
import './routes/routes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// 去掉右上角debug图标
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// 全局配置主题
appBarTheme: const AppBarTheme(
// 主题标题全部居中显示
centerTitle: true
),
),
// home: const Tabs(),
// 初始化路由
initialRoute: "/",
// 固定写法,配置onGenerateRoute
onGenerateRoute: onGenerateRoute,
);
}
}
4-4 home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/pageViewFullPage");
},
child: const Text("PageView上拉无限加载演示"),
),
],
),
);
}
}
4-5 routes.dart
import '../pages/tabs.dart';
import '../pages/pageViewFullPage.dart';
// 配置iOS风格的路由,引入库
import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// 定义一个Map类型的路由
Map routes = {
"/": (context) => const Tabs(),
"/pageViewFullPage": (context) => const PageViewFullPage(),
};
// 配置onGenerateRoute,固定写法,该方法相当于一个中间件,可以做权限判断
// ignore: prefer_function_declarations_over_variables
var onGenerateRoute = (RouteSettings settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
// final Route route = MaterialPageRoute(
// 替换MaterialPageRoute
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(
context, arguments: settings.arguments
)
);
return route;
} else {
// final Route route = MaterialPageRoute(
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(context)
);
return route;
}
}
return null;
};
4-6 setting.dart
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("系统设置"),
);
}
}
4-7 category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({Key? key}) : super(key: key);
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类页面"),
);
}
}
4-8 pageViewFullPage.dart
import 'package:flutter/material.dart';
class PageViewFullPage extends StatefulWidget {
const PageViewFullPage({Key? key}) : super(key: key);
@override
State<PageViewFullPage> createState() => _PageViewFullPageState();
}
class _PageViewFullPageState extends State<PageViewFullPage> {
List<Widget> list=[];
@override
void initState() {
super.initState();
for(var i=0; i<10; i++) {
list.add(
Center(
child: Text("第${i+1}屏", style: const TextStyle(fontSize: 60)),
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("屏幕标题")),
body: PageView(
scrollDirection: Axis.vertical,
onPageChanged: (index) {
print(index);
if(index+2==list.length) {
setState(() {
for(var i=0; i<10; i++) {
list.add(
Center(
child: Text("第${i+1}屏", style: const TextStyle(fontSize: 60)),
),
);
}
});
}
},
children: list,
),
);
}
}
5 实现图片无限轮播
# myflutter(项目名)目录结构如下
- pages/
- tabs/
- user.dart
- home.dart
- setting.dart
- category.dart
- tabs.dart
- pageViewSwiper.dart
- routes/
- routes.dart
- widget/
- image.dart
- main.dart
5-1 user.dart
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("用户信息"),
);
}
}
5-2 tabs.dart
import './tabs/user.dart';
import './tabs/home.dart';
import './tabs/setting.dart';
import './tabs/category.dart';
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({Key? key, this.index=0}) : super(key: key);
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(), CategoryPage(), SettingPage(), UserPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("实现图片无限轮播")),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 选中的颜色
fixedColor: Colors.red,
// 配置底部菜单大小
iconSize: 40,
// 4个以上菜单需配置此项
type: BottomNavigationBarType.fixed,
// 默认选中分类(第二个)
// currentIndex: 1,
currentIndex: _currentIndex,
onTap: (index){
// 获取点击的索引值
// print(index);
// 注意调用setState
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon:Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon:Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon:Icon(Icons.settings),
label: "设置",
),
// 没有type菜单图标会被挤掉
BottomNavigationBarItem(
icon:Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
5-3 main.dart
import './routes/routes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// 去掉右上角debug图标
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// 全局配置主题
appBarTheme: const AppBarTheme(
// 主题标题全部居中显示
centerTitle: true
),
),
// home: const Tabs(),
// 初始化路由
initialRoute: "/",
// 固定写法,配置onGenerateRoute
onGenerateRoute: onGenerateRoute,
);
}
}
5-4 home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/pageViewSwiper");
},
child: const Text("PageViewSwiper"),
),
],
),
);
}
}
5-5 image.dart
import 'package:flutter/material.dart';
class ImagePage extends StatelessWidget {
final double width; final double height; final String src;
const ImagePage({
Key? key, this.width=double.infinity, this.height=200, required this.src
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
height: height,
child: Image.network(src, fit: BoxFit.cover),
);
}
}
5-6 routes.dart
import '../pages/tabs.dart';
import '../pages/pageViewSwiper.dart';
// 配置iOS风格的路由,引入库
import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// 定义一个Map类型的路由
Map routes = {
"/": (context) => const Tabs(),
"/pageViewSwiper": (context) => const PageViewSwiper(),
};
// 配置onGenerateRoute,固定写法,该方法相当于一个中间件,可以做权限判断
// ignore: prefer_function_declarations_over_variables
var onGenerateRoute = (RouteSettings settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
// final Route route = MaterialPageRoute(
// 替换MaterialPageRoute
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(
context, arguments: settings.arguments
)
);
return route;
} else {
// final Route route = MaterialPageRoute(
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(context)
);
return route;
}
}
return null;
};
5-7 setting.dart
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("系统设置"),
);
}
}
5-8 category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({Key? key}) : super(key: key);
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类页面"),
);
}
}
5-9 pageViewSwiper.dart
import '../widget/image.dart';
import 'package:flutter/material.dart';
class PageViewSwiper extends StatefulWidget {
const PageViewSwiper({Key? key}) : super(key: key);
@override
State<PageViewSwiper> createState() => _PageViewSwiperState();
}
class _PageViewSwiperState extends State<PageViewSwiper> {
List<Widget> list=[]; int _currentIndex=0;
@override
void initState() {
super.initState();
list = const [
ImagePage(src: "https://t.hk.uy/b8Rq"),
ImagePage(src: "https://t.hk.uy/b8Rr"),
ImagePage(src: "https://t.hk.uy/b8Rs"),
ImagePage(src: "https://t.hk.uy/b8Rt"),
ImagePage(src: "https://t.hk.uy/b8Ru"),
ImagePage(src: "https://t.hk.uy/b8Rv"),
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("PageViewSwiper")),
body: Stack(
children: [
SizedBox(
height: 630,
child: PageView.builder(
onPageChanged: (index) {
// 刚开始 _currentIndex=0
setState(() {
// index=1---1 ... index=6---0
_currentIndex=index % list.length;
});
},
itemCount: 1000,
// index值为0-1000
itemBuilder: (context, index) {
return list[index%list.length];
},
),
),
Positioned(
// left和right为0,占满整行
left: 0, right: 0, bottom: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(list.length, (index) {
return Container(
margin: const EdgeInsets.all(5),
width: 10, height: 10,
decoration: BoxDecoration(
color: _currentIndex==index?Colors.white:Colors.grey,
// 同borderRadius
shape: BoxShape.circle,
// borderRadius: BorderRadius.circular(5),
),
);
}).toList(),
),
),
],
),
);
}
}
6 Flutter实现定时器
# myflutter(项目名)目录结构如下
- pages/
- tabs/
- user.dart
- home.dart
- setting.dart
- category.dart
- tabs.dart
- pageViewSwiper.dart
- routes/
- routes.dart
- widget/
- swiper.dart
- main.dart
6-1 user.dart
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("用户信息"),
);
}
}
6-2 tabs.dart
import './tabs/user.dart';
import './tabs/home.dart';
import './tabs/setting.dart';
import './tabs/category.dart';
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({Key? key, this.index=0}) : super(key: key);
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(), CategoryPage(), SettingPage(), UserPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter实现定时器")),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 选中的颜色
fixedColor: Colors.red,
// 配置底部菜单大小
iconSize: 40,
// 4个以上菜单需配置此项
type: BottomNavigationBarType.fixed,
// 默认选中分类(第二个)
// currentIndex: 1,
currentIndex: _currentIndex,
onTap: (index){
// 获取点击的索引值
// print(index);
// 注意调用setState
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon:Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon:Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon:Icon(Icons.settings),
label: "设置",
),
// 没有type菜单图标会被挤掉
BottomNavigationBarItem(
icon:Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
6-3 main.dart
import './routes/routes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// 去掉右上角debug图标
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// 全局配置主题
appBarTheme: const AppBarTheme(
// 主题标题全部居中显示
centerTitle: true
),
),
// home: const Tabs(),
// 初始化路由
initialRoute: "/",
// 固定写法,配置onGenerateRoute
onGenerateRoute: onGenerateRoute,
);
}
}
6-4 home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/pageViewSwiper");
},
child: const Text("PageViewSwiper"),
),
],
),
);
}
}
6-5 routes.dart
import '../pages/tabs.dart';
import '../pages/pageViewSwiper.dart';
// 配置iOS风格的路由,引入库
import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// 定义一个Map类型的路由
Map routes = {
"/": (context) => const Tabs(),
"/pageViewSwiper": (context) => const PageViewSwiper(),
};
// 配置onGenerateRoute,固定写法,该方法相当于一个中间件,可以做权限判断
// ignore: prefer_function_declarations_over_variables
var onGenerateRoute = (RouteSettings settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
// final Route route = MaterialPageRoute(
// 替换MaterialPageRoute
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(
context, arguments: settings.arguments
)
);
return route;
} else {
// final Route route = MaterialPageRoute(
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(context)
);
return route;
}
}
return null;
};
6-6 swiper.dart
import 'package:flutter/material.dart';
class Swiper extends StatefulWidget {
final double width; final double height; final List<String> list;
const Swiper({
Key? key, this.width=double.infinity, this.height=200, required this.list
}) : super(key: key);
@override
State<Swiper> createState() => _SwiperState();
}
class _SwiperState extends State<Swiper> {
int _currentIndex=0;
List<Widget> pageList=[];
@override
void initState() {
super.initState();
for(var i=0; i<widget.list.length; i++) {
pageList.add(
ImagePage(
width: widget.width, height: widget.height, src: widget.list[i],
),
);
}
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
SizedBox(
height: 605,
child: PageView.builder(
onPageChanged: (index) {
// 刚开始 _currentIndex=0
setState(() {
// index=1---1 ... index=6---0
_currentIndex=index % pageList.length;
});
},
itemCount: 1000,
// index值为0-1000
itemBuilder: (context, index) {
return pageList[index % pageList.length];
},
),
),
Positioned(
// left和right为0,占满整行
left: 0, right: 0, bottom: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(pageList.length, (index) {
return Container(
margin: const EdgeInsets.all(5),
width: 10, height: 10,
decoration: BoxDecoration(
color: _currentIndex==index?Colors.white:Colors.grey,
// 同borderRadius
shape: BoxShape.circle,
// borderRadius: BorderRadius.circular(5),
),
);
}).toList(),
),
),
],
);
}
}
class ImagePage extends StatelessWidget {
final double width; final double height; final String src;
const ImagePage({
Key? key, this.width=double.infinity, this.height=200, required this.src
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
height: height,
child: Image.network(src, fit: BoxFit.cover),
);
}
}
6-7 setting.dart
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("系统设置"),
);
}
}
6-8 category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({Key? key}) : super(key: key);
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类页面"),
);
}
}
6-9 pageViewSwiper.dart
import 'dart:async';
import '../widget/swiper.dart';
import 'package:flutter/material.dart';
class PageViewSwiper extends StatefulWidget {
const PageViewSwiper({Key? key}) : super(key: key);
@override
State<PageViewSwiper> createState() => _PageViewSwiperState();
}
class _PageViewSwiperState extends State<PageViewSwiper> {
// List<Widget> list=[];
List<String> list=[];
@override
void initState() {
super.initState();
list = const [
"https://t.hk.uy/b8Rq", "https://t.hk.uy/b8Rr",
"https://t.hk.uy/b8Rs", "https://t.hk.uy/b8Rt",
"https://t.hk.uy/b8Ru", "https://t.hk.uy/b8Rv",
// ImagePage(src: "https://t.hk.uy/b8Rq"),
// ImagePage(src: "https://t.hk.uy/b8Rr"),
// ImagePage(src: "https://t.hk.uy/b8Rs"),
// ImagePage(src: "https://t.hk.uy/b8Rt"),
// ImagePage(src: "https://t.hk.uy/b8Ru"),
// ImagePage(src: "https://t.hk.uy/b8Rv"),
];
// 创建定时器,每隔3秒钟打印一句“执行”
Timer t=Timer.periodic(const Duration(seconds: 3), (timer) {
print("执行");
// timer.cancel();
});
// t.cancel();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("PageViewSwiper")),
body: ListView(
children: [
Swiper(list: list)
],
),
);
}
}
7 实现图片动态轮播
# myflutter(项目名)目录结构如下
- pages/
- tabs/
- user.dart
- home.dart
- setting.dart
- category.dart
- tabs.dart
- pageViewSwiper.dart
- routes/
- routes.dart
- widget/
- swiper.dart
- main.dart
7-1 user.dart
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("用户信息"),
);
}
}
7-2 tabs.dart
import './tabs/user.dart';
import './tabs/home.dart';
import './tabs/setting.dart';
import './tabs/category.dart';
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({Key? key, this.index=0}) : super(key: key);
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(), CategoryPage(), SettingPage(), UserPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("实现图片动态轮播")),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 选中的颜色
fixedColor: Colors.red,
// 配置底部菜单大小
iconSize: 40,
// 4个以上菜单需配置此项
type: BottomNavigationBarType.fixed,
// 默认选中分类(第二个)
// currentIndex: 1,
currentIndex: _currentIndex,
onTap: (index){
// 获取点击的索引值
// print(index);
// 注意调用setState
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon:Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon:Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon:Icon(Icons.settings),
label: "设置",
),
// 没有type菜单图标会被挤掉
BottomNavigationBarItem(
icon:Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
7-3 main.dart
import './routes/routes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// 去掉右上角debug图标
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// 全局配置主题
appBarTheme: const AppBarTheme(
// 主题标题全部居中显示
centerTitle: true
),
),
// home: const Tabs(),
// 初始化路由
initialRoute: "/",
// 固定写法,配置onGenerateRoute
onGenerateRoute: onGenerateRoute,
);
}
}
7-4 home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/pageViewSwiper");
},
child: const Text("PageViewSwiper"),
),
],
),
);
}
}
7-5 routes.dart
import '../pages/tabs.dart';
import '../pages/pageViewSwiper.dart';
// 配置iOS风格的路由,引入库
import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// 定义一个Map类型的路由
Map routes = {
"/": (context) => const Tabs(),
"/pageViewSwiper": (context) => const PageViewSwiper(),
};
// 配置onGenerateRoute,固定写法,该方法相当于一个中间件,可以做权限判断
// ignore: prefer_function_declarations_over_variables
var onGenerateRoute = (RouteSettings settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
// final Route route = MaterialPageRoute(
// 替换MaterialPageRoute
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(
context, arguments: settings.arguments
)
);
return route;
} else {
// final Route route = MaterialPageRoute(
final Route route = CupertinoPageRoute(
builder: (context) => pageContentBuilder(context)
);
return route;
}
}
return null;
};
7-6 swiper.dart
import 'dart:async';
import 'package:flutter/material.dart';
class Swiper extends StatefulWidget {
final double width; final double height; final List<String> list;
const Swiper({
Key? key, this.width=double.infinity, this.height=200, required this.list
}) : super(key: key);
@override
State<Swiper> createState() => _SwiperState();
}
class _SwiperState extends State<Swiper> {
int _currentIndex=0;
List<Widget> pageList=[];
late PageController _pageController;
late Timer timer;
@override
void initState() {
super.initState();
// 数据
for(var i=0; i<widget.list.length; i++) {
pageList.add(
ImagePage(
width: widget.width, height: widget.height, src: widget.list[i],
),
);
}
// PageController
_pageController=PageController(initialPage: 0);
timer = Timer.periodic(const Duration(seconds: 5), (t) {
// 实现图片5秒动态轮播
_pageController.animateToPage(
(_currentIndex+1)%pageList.length,
duration: const Duration(milliseconds: 200),
curve: Curves.linear,
);
});
}
@override
void dispose() {
super.dispose();
timer.cancel();
_pageController.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
SizedBox(
height: 605,
child: PageView.builder(
controller: _pageController,
onPageChanged: (index) {
// 刚开始 _currentIndex=0
setState(() {
// index=1---1 ... index=6---0
_currentIndex=index % pageList.length;
});
},
itemCount: 1000,
// index值为0-1000
itemBuilder: (context, index) {
return pageList[index % pageList.length];
},
),
),
Positioned(
// left和right为0,占满整行
left: 0, right: 0, bottom: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(pageList.length, (index) {
return Container(
margin: const EdgeInsets.all(5),
width: 10, height: 10,
decoration: BoxDecoration(
color: _currentIndex==index?Colors.white:Colors.grey,
// 同borderRadius
shape: BoxShape.circle,
// borderRadius: BorderRadius.circular(5),
),
);
}).toList(),
),
),
],
);
}
}
class ImagePage extends StatelessWidget {
final double width; final double height; final String src;
const ImagePage({
Key? key, this.width=double.infinity, this.height=200, required this.src
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
height: height,
child: Image.network(src, fit: BoxFit.cover),
);
}
}
7-7 setting.dart
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("系统设置"),
);
}
}
7-8 category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({Key? key}) : super(key: key);
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类页面"),
);
}
}
7-9 pageViewSwiper.dart
import 'dart:async';
import '../widget/swiper.dart';
import 'package:flutter/material.dart';
class PageViewSwiper extends StatefulWidget {
const PageViewSwiper({Key? key}) : super(key: key);
@override
State<PageViewSwiper> createState() => _PageViewSwiperState();
}
class _PageViewSwiperState extends State<PageViewSwiper> {
// List<Widget> list=[];
List<String> list=[];
@override
void initState() {
super.initState();
list = const [
"https://t.hk.uy/b8Rq", "https://t.hk.uy/b8Rr",
"https://t.hk.uy/b8Rs", "https://t.hk.uy/b8Rt",
"https://t.hk.uy/b8Ru", "https://t.hk.uy/b8Rv",
// ImagePage(src: "https://t.hk.uy/b8Rq"),
// ImagePage(src: "https://t.hk.uy/b8Rr"),
// ImagePage(src: "https://t.hk.uy/b8Rs"),
// ImagePage(src: "https://t.hk.uy/b8Rt"),
// ImagePage(src: "https://t.hk.uy/b8Ru"),
// ImagePage(src: "https://t.hk.uy/b8Rv"),
];
// 创建定时器,每隔3秒钟打印一句“执行”
Timer t=Timer.periodic(const Duration(seconds: 3), (timer) {
print("执行");
// timer.cancel();
});
// t.cancel();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("PageViewSwiper")),
body: ListView(
children: [
Swiper(list: list)
],
),
);
}
}