const 常量构造函数,如果控件是,则前面加;如果常量构造函数包含有非常量构造函数,则不加,内部是的控件单独加
Flutter 中文官网 https://flutter.cn/
Flutter 官网:https://flutter.dev/
Flutter Packages官网:https://pub.dev/
第8步提前操作
Flutter Android 环境搭建
Flutter sdk(使用最新版本) 下载路径 https://docs.flutter.dev/development/tools/sdk/releases?tab=windows#windows
Flutter 国内镜像地址 https://docs.flutter.dev/community/china
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
git clone -b dev https://github.com/flutter/flutter.git
export PATH="$PWD/flutter/bin:$PATH"
cd ./flutter
flutter doctor



Visual Studio 如果需要开发桌面应用 https://visualstudio.microsoft.com/downloads/
C++ CMake tools for Windows 必须下载 1.5G
#### 6.AS 新建flutter项目 (项目目录都是小写)


vs下载路径:https://code.visualstudio.com/
插件:fluter dart Awesome FlutterSnippets(flutter提示工具)
不同的插件,快捷方式不一样


vs 打开flutter文件夹
flutter run
flutter run -d all
ctrl+s 保存
常用快捷键(鼠标点到控制台)
r键:点击后热加载,也算是重新加载
R键:热重启项目
P键:显示网络,这个可以很好的掌握布局情况,工作中很有用
o键:切换Android和ios的预览模式
q键 :退出调试模式 ctrl+c
lib 项目目录
pubspec.yaml 配置文件 项目依赖 项目版本号
analysis_options.yaml 分析dart语法文件,老项目升级成新项目有警告信息的话可以删掉此文件,可以全部删掉,有利于语法规范

import 'package:flutter/material.dart';void main() {runApp(MaterialApp(home: Scaffold(appBar: AppBar(title: const Text("你好Flutter")),body: HomeWidge(),),));
}class HomeWidge extends StatelessWidget {@overrideWidget build(BuildContext context) {return const Center(child: Text("我是一个文本",textDirection: TextDirection.ltr,style: TextStyle(fontSize: 25.0, color: Colors.red)));}
}
const(常量构造函数) 规范 ,也可以不加
import 'package:flutter/material.dart';void main() {runApp(MaterialApp(home: Scaffold(appBar: AppBar(title: const Text("你好Flutter")),body: Column(children: [MyApp(), MyButton(), MyText()],),),));
}class HomeWidge extends StatelessWidget {@overrideWidget build(BuildContext context) {return const Center(child: Text("我是一个文本",textDirection: TextDirection.ltr,style: TextStyle(fontSize: 25.0, color: Colors.red)));}
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Center(child: Container(margin: const EdgeInsets.fromLTRB(0, 60, 0, 0),alignment: Alignment.center,height: 200,width: 200,// transform: Matrix4.skewY(0.2),decoration: BoxDecoration(color: Colors.yellow,gradient: const LinearGradient(colors: [Colors.red, Colors.orange]),boxShadow: const [BoxShadow(color: Colors.blue,offset: Offset(2.0, 2.0),blurRadius: 10.0,)],border: Border.all(color: Colors.red, width: 2),borderRadius: BorderRadius.circular(8)),child: const Text("你好Flutter",style: TextStyle(fontSize: 20),),),);}
}class MyButton extends StatelessWidget {const MyButton({super.key});@overrideWidget build(BuildContext context) {return Container(alignment: Alignment.center,width: 200,height: 40,decoration: BoxDecoration(color: Colors.blue,borderRadius: BorderRadius.circular(10),),margin: const EdgeInsets.fromLTRB(0, 40, 0, 0),child: const Text("按钮",style: TextStyle(color: Colors.white,fontSize: 20,)),);}
}class MyText extends StatelessWidget {const MyText({super.key});@overrideWidget build(BuildContext context) {return Container(alignment: Alignment.center,width: 200,height: 200,decoration: const BoxDecoration(color: Colors.yellow,),child: const Text("如果是负值,会让单词变得更紧凑如果是负值,会让单词变得更紧凑",textAlign: TextAlign.left,maxLines: 2,overflow: TextOverflow.ellipsis,style: TextStyle(fontSize: 20.0,fontWeight: FontWeight.bold,color: Colors.red,fontStyle: FontStyle.italic),),);}
}
上下间距
SizedBox( height: 20)
import 'package:flutter/material.dart';class MyApp2 extends StatelessWidget {const MyApp2({super.key});@overrideWidget build(BuildContext context) {return Center(child: Container(width: 150,height: 150,alignment: Alignment.center,decoration: BoxDecoration(color: Colors.yellow,borderRadius: BorderRadius.circular(10),image: const DecorationImage(fit: BoxFit.cover,image: NetworkImage("https://www.itying.com/themes/itying/images/ionic4.png"))),// child: Image.network(// "https://www.itying.com/themes/itying/images/ionic4.png",// fit: BoxFit.cover,// ),),);}
}//实现圆形图片
class Circular extends StatelessWidget {const Circular({super.key});@overrideWidget build(BuildContext context) {return Center(child: ClipOval(child: Image.network("https://www.itying.com/themes/itying/images/ionic4.png",width: 150.0,height: 150.0,fit: BoxFit.cover,),),);}
}class LocationImg extends StatelessWidget {const LocationImg({super.key});@overrideWidget build(BuildContext context) {return Center(child: ClipOval(child: Image.asset("images/a.jpg",width: 150.0,height: 150.0,fit: BoxFit.cover,),),);}
}
用处不大
| GridView.count | GridView.extent | |
|---|---|---|
| crossAxisCount 一行的Widget数量 | maxCrossAxisExtent 横轴子元素的最大长度 | |
| gridDelegate | SliverGridDelegateWithFixedCrossAxisCount | SliverGridDelegateWithMaxCrossAxisExtent |
import 'package:flutter/material.dart';
import 'package:flutter01/res/listData.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(theme: ThemeData(primarySwatch: Colors.yellow),home: Scaffold(appBar: AppBar(title: Text("Fluter app")),body: MyHomePage(),),);}
}class MyHomePage extends StatelessWidget {const MyHomePage({super.key});Widget _initGridViewData(context, index) {return Container(decoration: BoxDecoration(border: Border.all(color: Colors.black26)),child: Column(children: [Image.network(listData[index]["imageUrl"]),const SizedBox(height: 10),Text(listData[index]["title"],style: const TextStyle(fontSize: 18),)],),);}@overrideWidget build(BuildContext context) {return GridView.builder(padding: const EdgeInsets.all(10),itemCount: listData.length,gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisSpacing: 10,mainAxisSpacing: 10,crossAxisCount: 2,childAspectRatio: 1),itemBuilder: _initGridViewData);}
}
List listData = [{"title": "Candy shop","author": "Mohamed Chain","imageUrl": "https://www.itying.com/images/flutter/1.png",},
];
this.icon 是 this.icon=icon; 的简写
required this.color 中 required 表明是必传参数
this.color = Colors.red 这个写,写可以不传
class IconContainer extends StatelessWidget {Color color;double size;IconData icon;IconContainer(this.icon,{Key? key, this.color = Colors.red, this.size = 32.0}): super(key: key);IconContainer1({Key? key, this.color = Colors.red, this.size = 32.0}): super(key: key) {
this.icon=icon;}@overrideWidget build(BuildContext context) {return Container(height: 100,width: 100,color: this.color,child: Icon(icon, color: color, size: size),);}
}
double.infinity 和double.maxFinite可以让当前元素的width或者height达到父元素的尺寸
底层代码,只能用在Container容器里
width: double.infinity,
height: double.infinity,
flex Expanded 弹性布局


FlutterMediaQuery获取屏幕宽度和高度
final size = MediaQuery.of(context).size;
size.width,

alignment: Alignment(-1, 1),
算法实现
(Alignment.xchildWidth/2+childWidth/2, Alignment.ychildHeight/2+childHeight/2)


import 'package:flutter/material.dart';
import 'package:flutter01/res/listData.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(theme: ThemeData(primarySwatch: Colors.yellow),home: Scaffold(appBar: AppBar(title: Text("Fluter app")),body: MyHomePage(),),);}
}class MyHomePage extends StatelessWidget {const MyHomePage({super.key});@overrideWidget build(BuildContext context) {final size = MediaQuery.of(context).size;return Column(children: [SizedBox(width: double.infinity,height: 40,child: Stack(children: const [Align(alignment: Alignment.topLeft,child: Text("收藏"),),Align(alignment: Alignment.topRight,child: Text("购买"),),],),),SizedBox(width: double.infinity,height: 40,child: Stack(children: const [Positioned(left: 10, child: Text("收藏")),Positioned(right: 10, child: Text("购买")),],),)],);}
}
用在控制图片的宽高比
AspectRatio(aspectRatio: 3 / 1,child: Container(color: Colors.red,),)

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(theme: ThemeData(primarySwatch: Colors.blue),home: Scaffold(appBar: AppBar(title: Text("Fluter app")),body: MyHomePage(),),);}
}class MyHomePage extends StatelessWidget {const MyHomePage({super.key});@overrideWidget build(BuildContext context) {final size = MediaQuery.of(context).size;return ListView(children: [Card(margin: EdgeInsets.all(10),elevation: 10,shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),child: Column(children: const [ListTile(title: Text("张三",style: TextStyle(fontSize: 28),),subtitle: Text("高级软甲女工程师"),),Divider(),ListTile(title: Text("电话:1443234564",),subtitle: Text("地址:xxxxx"),)],),),Card(margin: EdgeInsets.all(10),child: Column(children: const [ListTile(title: Text("李四",style: TextStyle(fontSize: 28),),subtitle: Text("高级软甲男工程师"),),Divider(),ListTile(title: Text("电话:1443234564",),subtitle: Text("地址:xxxxx"),)],),)],);}
}

ListView(children: [Card(margin: const EdgeInsets.all(10),elevation: 20,shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),child: Column(children: [AspectRatio(aspectRatio: 16 / 9,child: Image.network("https://www.itying.com/images/flutter/1.png",fit: BoxFit.cover,),),ListTile(leading: ClipOval(child: Image.network("https://www.itying.com/images/flutter/2.png",fit: BoxFit.cover,height: 40,width: 40,)),title: const Text("XXXXXXX"),subtitle: const Text("aaaaaaaaa"),)],),)],)
CircleAvatar(backgroundImage: NetworkImage("https://www.itying.com/images/flutter/3.png"),)
ClipOval(child: Image.network("https://www.itying.com/images/flutter/2.png",fit: BoxFit.cover,height: 40,width: 40,))

import 'package:flutter/material.dart';
import './res/listData.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(theme: ThemeData(primarySwatch: Colors.blue),home: Scaffold(appBar: AppBar(title: Text("Fluter app")),body: MyHomePage(),),);}
}class MyHomePage extends StatelessWidget {const MyHomePage({super.key});List _initCardDate() {var tempList = listData.map((value) {return Card(margin: const EdgeInsets.all(10),elevation: 20,shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),child: Column(children: [AspectRatio(aspectRatio: 16 / 9,child: Image.network(value["imageUrl"],fit: BoxFit.cover,),),ListTile(leading: CircleAvatar(backgroundImage: NetworkImage(value["imageUrl"]),),title: Text(value["title"]),subtitle: Text(value["author"]),)],),);});return tempList.toList();}@overrideWidget build(BuildContext context) {final size = MediaQuery.of(context).size;return ListView(children: _initCardDate(),);}
}
19

import 'package:flutter/material.dart';
import './res/listData.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(theme: ThemeData(primarySwatch: Colors.blue),home: Scaffold(appBar: AppBar(title: Text("Fluter app")),body: MyHomePage(),),);}
}class MyHomePage extends StatelessWidget {const MyHomePage({super.key});@overrideWidget build(BuildContext context) {final size = MediaQuery.of(context).size;return ListView(children: [Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [ElevatedButton(onPressed: () {print("ElevatedButton");},child: const Text("普通按钮")),TextButton(onPressed: () {}, child: const Text("文本按钮")),OutlinedButton(onPressed: () {}, child: const Text("带边框的按钮")),IconButton(onPressed: () {}, icon: const Icon(Icons.thumb_up))],),const SizedBox(height: 20,),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [ElevatedButton.icon(onPressed: () {},icon: const Icon(Icons.thumb_up),label: const Text("点赞")),TextButton.icon(onPressed: () {},icon: const Icon(Icons.thumb_up),label: const Text("点赞")),OutlinedButton.icon(onPressed: () {},icon: const Icon(Icons.thumb_up),label: const Text("点赞")),],),const SizedBox(height: 20,),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [ElevatedButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.red),foregroundColor: MaterialStateProperty.all(Colors.black)),onPressed: () {},child: const Text("普通按钮")),],),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [Container(width: 140,height: 60,child: ElevatedButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.red),foregroundColor: MaterialStateProperty.all(Colors.white)),onPressed: () {},child: const Text("大按钮")),),SizedBox(width: 140,height: 40,child: ElevatedButton(onPressed: () {}, child: const Text("大按钮")),)],),const SizedBox(height: 20,),Row(children: [Expanded(flex: 1,child: Container(margin: const EdgeInsets.all(20),height: 44,child: ElevatedButton(style: ButtonStyle(backgroundColor:MaterialStateProperty.all(Colors.redAccent),foregroundColor:MaterialStateProperty.all(Colors.white)),onPressed: () {},child: const Text("登录")),),)],),const SizedBox(height: 20,),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [ElevatedButton(style: ButtonStyle(shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)))),onPressed: () {},child: const Text("圆角按钮")),Container(height: 60,width: 60,child: ElevatedButton(style: ButtonStyle(shape: MaterialStateProperty.all(const CircleBorder(side: BorderSide(width: 2, color: Colors.yellow)))),onPressed: () {},child: const Text("圆形")),)],),SizedBox(height: 20,),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [OutlinedButton(onPressed: () {},child: const Text("带边框的按钮"),style: ButtonStyle(side: MaterialStateProperty.all(BorderSide(width: 1, color: Colors.red))),)],)],);}
}
21
ListView 不能嵌套ListView

import 'package:flutter/material.dart';
import './res/listData.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(theme: ThemeData(primarySwatch: Colors.blue),home: Scaffold(appBar: AppBar(title: Text("Fluter app")),body: MyHomePage(),),);}
}class MyHomePage extends StatelessWidget {const MyHomePage({super.key});@overrideWidget build(BuildContext context) {final size = MediaQuery.of(context).size;return ListView(padding: const EdgeInsets.all(10),children: [Row(children: [Text('热搜', style: Theme.of(context).textTheme.titleLarge)],),const Divider(),Wrap(spacing: 10,runSpacing: 10,children: [Button("女装", onPressed: () {}),Button("女装", onPressed: () {}),Button("女装", onPressed: () {}),Button("女装", onPressed: () {}),Button("女装", onPressed: () {}),Button("女装", onPressed: () {}),Button("女装", onPressed: () {}),Button("女装", onPressed: () {}),],),const SizedBox(height: 10,),Row(children: [Text('历史记录', style: Theme.of(context).textTheme.titleLarge)],),const Divider(),Column(children: const [ListTile(title: Text("女装"),),Divider(),ListTile(title: Text("笔记本"),),Divider(),ListTile(title: Text("手电筒"),),Divider(),],),const SizedBox(height: 40,),Padding(padding: const EdgeInsets.all(40),child: OutlinedButton.icon(style: ButtonStyle(foregroundColor: MaterialStateProperty.all(Colors.black45)),onPressed: () {},icon: const Icon(Icons.delete),label: const Text("清空历史记录",)),)],);}
}//自定义按钮组件
class Button extends StatelessWidget {String text; //按钮的文字void Function()? onPressed; //方法Button(this.text, {super.key, required this.onPressed});@overrideWidget build(BuildContext context) {return ElevatedButton(style: ButtonStyle(backgroundColor:MaterialStateProperty.all(Color.fromARGB(31, 248, 247, 247)),foregroundColor: MaterialStateProperty.all(Colors.black45)),onPressed: onPressed,child: Text(text));}
}
setState(() {
});
通俗的讲:如果我们想改变页面中的数据的话这个时候就需要用到StatefulWidget
21
里面是const 就无法在外面加const
//有状态组件
class _HomePageState extends State {int _countNum = 0;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Fluter app")),floatingActionButton: FloatingActionButton(onPressed: () {setState(() {_countNum++;});},child: const Icon(Icons.add),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text("$_countNum",style: Theme.of(context).textTheme.headline1,),const SizedBox(height: 100,),ElevatedButton(onPressed: () {setState(() {_countNum++;});print(_countNum);},child: const Text("增加"))],),),);}
}

//有状态组件
class _HomePageState extends State {final List _list = [];@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Fluter app")),floatingActionButton: FloatingActionButton(onPressed: () {setState(() {_list.add("我是一个新增列表");});},child: const Icon(Icons.add),),body: ListView(children: _list.map((value) {return ListTile(title: Text(value));}).toList(),),);}
}

import 'package:flutter/material.dart';
import './tabs/home.dart';
import './tabs/category.dart';
import './tabs/setting.dart';
import './tabs/user.dart';class MyHomePage extends StatefulWidget {const MyHomePage({super.key});@overrideState createState() => _MyHomePageState();
}//有状态组件
class _MyHomePageState extends State {int _currentIndex = 0;final List _pages = [HomePage(),Category(),SettingPage(),UserPage()];@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Fluter app")),bottomNavigationBar: BottomNavigationBar(fixedColor: Colors.red, //选中的颜色iconSize: 25, //底部菜单大小currentIndex: _currentIndex, //第几个菜单选项type: BottomNavigationBarType.fixed, //如果底部有四个以上的菜单的时候,就需要配置这个参数onTap: (index) {//点击选项触发的方法setState(() {_currentIndex = index;});},items: const [BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),BottomNavigationBarItem(icon: Icon(Icons.person), label: "个人")],),body: _pages[_currentIndex],);}
}

import 'package:flutter/material.dart';
import './tabs/home.dart';
import './tabs/category.dart';
import './tabs/setting.dart';
import './tabs/user.dart';
import './tabs/message.dart';class MyHomePage extends StatefulWidget {const MyHomePage({super.key});@overrideState createState() => _MyHomePageState();
}//有状态组件
class _MyHomePageState extends State {int _currentIndex = 0;final List _pages = [HomePage(),Category(),MessagePage(),SettingPage(),UserPage()];@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Fluter app")),bottomNavigationBar: BottomNavigationBar(fixedColor: Colors.red, //选中的颜色iconSize: 25, //底部菜单大小currentIndex: _currentIndex, //第几个菜单选项type: BottomNavigationBarType.fixed, //如果底部有四个以上的菜单的时候,就需要配置这个参数onTap: (index) {//点击选项触发的方法setState(() {_currentIndex = index;});},items: const [BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),BottomNavigationBarItem(icon: Icon(Icons.message), label: "消息"),BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),BottomNavigationBarItem(icon: Icon(Icons.person), label: "个人")],),floatingActionButton: Container(height: 60,width: 60,padding: const EdgeInsets.all(4),margin: const EdgeInsets.only(top: 4),decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(30)),child: FloatingActionButton(backgroundColor: _currentIndex == 2 ? Colors.red : Colors.blue,onPressed: () {setState(() {_currentIndex = 2;});},child: const Icon(Icons.add),),),floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,body: _pages[_currentIndex],);}
}
在Scaffold组件里面传入drawer参数可以定义左侧边栏,传入endDrawer可以定义右侧边栏。侧边栏默认是隐藏的,我们可以通过手指滑动显示侧边栏,也可以通过点击按钮显示侧边栏。

在上一个代码中增加以下代码
drawer: Drawer(child: Column(children: [DrawerHeader(decoration: const BoxDecoration(color: Colors.yellow,image: DecorationImage(image: NetworkImage("https://www.itying.com/images/flutter/2.png"),fit: BoxFit.cover)),child: ListView(children: [Text('我是一个头部')],),),const ListTile(title: Text("个人中心"),leading: CircleAvatar(child: Icon(Icons.people)),),const Divider(),const ListTile(title: Text("系统设置"),leading: CircleAvatar(child: Icon(Icons.settings)),)],)),

drawer: Drawer(child: Column(children: [UserAccountsDrawerHeader(accountName: const Text("大地老师"),accountEmail: const Text("dadi@itying.com"),currentAccountPicture: const CircleAvatar(backgroundImage:NetworkImage("https://www.itying.com/images/flutter/3.png"),),decoration: const BoxDecoration(color: Colors.yellow,image: DecorationImage(image: NetworkImage("https://www.itying.com/images/flutter/2.png"),fit: BoxFit.cover)),otherAccountsPictures: [Image.network("https://www.itying.com/images/flutter/4.png"),Image.network("https://www.itying.com/images/flutter/5.png"),Image.network("https://www.itying.com/images/flutter/6.png")],),const ListTile(title: Text("个人中心"),leading: CircleAvatar(child: Icon(Icons.people)),),const Divider(),const ListTile(title: Text("系统设置"),leading: CircleAvatar(child: Icon(Icons.settings)),)],)),

appBar: AppBar(backgroundColor: Colors.red, //导航栏背景颜色leading: IconButton(//左侧按钮图标icon: const Icon(Icons.menu),onPressed: () {print('menu Pressed');}),title: const Text('FlutterDemo'),actions: [//右侧按钮图标IconButton(icon: const Icon(Icons.search),onPressed: () {print('Search Pressed');}),IconButton(icon: const Icon(Icons.more_horiz),onPressed: () {print('more_horiz Pressed');})],),
class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,//去掉debug样式theme: ThemeData(primarySwatch: Colors.blue),home: HomePage(),);}
}

class _HomePageState extends Statewith SingleTickerProviderStateMixin {late TabController _tabController;//生命周期函数:当前组件初始化的时候就会触发@overridevoid initState() {super.initState();_tabController = TabController(length: 3, vsync: this);_tabController.addListener(() {if (_tabController.animation!.value == _tabController.index) {print(_tabController.index); //获取点击或滑动页面的索引值}});}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(bottom: TabBar(isScrollable: true,indicatorColor: Colors.white,indicatorWeight: 2,indicatorPadding: EdgeInsets.all(5),indicatorSize: TabBarIndicatorSize.label,// indicator: BoxDecoration(// color: Colors.blue, borderRadius: BorderRadius.circular(10)),controller: _tabController,tabs: const [Tab(child: Text("热门")),Tab(child: Text("推荐")),Tab(child: Text("视频"))],),),body: TabBarView(controller: _tabController,children: const [Text("热门"), Text("推荐"), Text("视频")],),);}
}
import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,theme: ThemeData(primarySwatch: Colors.blue),home: HomePage(),);}
}class HomePage extends StatefulWidget {const HomePage({super.key});@overrideState createState() => _HomePageState();
}class _HomePageState extends Statewith SingleTickerProviderStateMixin {late TabController _tabController;//生命周期函数:当前组件初始化的时候就会触发@overridevoid initState() {super.initState();_tabController = TabController(length: 3, vsync: this);_tabController.addListener(() {if (_tabController.animation!.value == _tabController.index) {print(_tabController.index); //获取点击或滑动页面的索引值}});}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(backgroundColor: Colors.red, //导航栏背景颜色leading: IconButton(//左侧按钮图标icon: const Icon(Icons.menu),onPressed: () {print('menu Pressed');}),title: const Text('FlutterDemo'),actions: [//右侧按钮图标IconButton(icon: const Icon(Icons.search),onPressed: () {print('Search Pressed');}),IconButton(icon: const Icon(Icons.more_horiz),onPressed: () {print('more_horiz Pressed');})],bottom: TabBar(isScrollable: true,indicatorColor: Colors.white,indicatorWeight: 2,indicatorPadding: EdgeInsets.all(5),indicatorSize: TabBarIndicatorSize.label,// indicator: BoxDecoration(// color: Colors.blue, borderRadius: BorderRadius.circular(10)),controller: _tabController,tabs: const [Tab(child: Text("热门")),Tab(child: Text("推荐")),Tab(child: Text("视频"))],),),body: TabBarView(controller: _tabController,children: const [Text("热门"), Text("推荐"), Text("视频")],),);}
}
HomePage 中写的代码
import 'package:flutter/material.dart';class HomePage extends StatefulWidget {const HomePage({super.key});@overrideState createState() => _HomePageState();
}class _HomePageState extends Statewith SingleTickerProviderStateMixin {late TabController _tabController;//生命周期函数:当前组件初始化的时候就会触发@overridevoid initState() {super.initState();_tabController = TabController(length: 3, vsync: this);_tabController.addListener(() {if (_tabController.animation!.value == _tabController.index) {print(_tabController.index); //获取点击或滑动页面的索引值}});}@overrideWidget build(BuildContext context) {return Scaffold(appBar: PreferredSize(preferredSize: Size.fromHeight(40),child: Container(height: 40,child: AppBar(elevation: 0.5,backgroundColor: Colors.white,centerTitle: true,title: TabBar(labelStyle: TextStyle(fontSize: 14),isScrollable: true,indicatorColor: Colors.red,labelColor: Colors.red,unselectedLabelColor: Colors.black,indicatorWeight: 2,indicatorPadding: EdgeInsets.all(5),indicatorSize: TabBarIndicatorSize.label,// indicator: BoxDecoration(// color: Colors.blue, borderRadius: BorderRadius.circular(10)),controller: _tabController,tabs: const [Tab(child: Text("热门")),Tab(child: Text("推荐")),Tab(child: Text("视频"))],),),),),body: TabBarView(controller: _tabController,children: const [Text("热门"), Text("推荐"), Text("视频")],),);}
}
Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
....
)
),
body: Test(),
)
解决: 跳转其它页面返回后,自动回到了顶部
引入之后,包括在需要缓冲的外层
KeepAliveWrapper
import 'package:flutter/material.dart';class KeepAliveWrapper extends StatefulWidget {const KeepAliveWrapper({Key? key, @required this.child, this.keepAlive = true}): super(key: key);final Widget? child;final bool keepAlive;@overrideState createState() => _KeepAliveWrapperState();
}class _KeepAliveWrapperState extends Statewith AutomaticKeepAliveClientMixin {@overrideWidget build(BuildContext context) {return widget.child!;}@overridebool get wantKeepAlive => widget.keepAlive;@overridevoid didUpdateWidget(covariant KeepAliveWrapper oldWidget) {if (oldWidget.keepAlive != widget.keepAlive) {
// keepAlive 状态需要更新,实现在 AutomaticKeepAliveClientMixin 中updateKeepAlive();}super.didUpdateWidget(oldWidget);}
}
//生命周期函数:当前组件初始化的时候就会触发@overridevoid initState() {super.initState();_tabController = TabController(length: 3, vsync: this);_tabController.addListener(() {//不判断回获取两次if (_tabController.animation!.value == _tabController.index) {print(_tabController.index); //获取点击或滑动页面的索引值}});}
TabBar(//只能监听点击事件,不能监听滑动onTap:(value) {},)
完整代码
import 'package:flutter/material.dart';
import '../tools/KeepAliveWrapper.dart';class HomePage extends StatefulWidget {const HomePage({super.key});@overrideState createState() => _HomePageState();
}class _HomePageState extends Statewith SingleTickerProviderStateMixin {late TabController _tabController;//生命周期函数:当前组件初始化的时候就会触发@overridevoid initState() {super.initState();_tabController = TabController(length: 3, vsync: this);_tabController.addListener(() {//不判断回获取两次if (_tabController.animation!.value == _tabController.index) {print(_tabController.index); //获取点击或滑动页面的索引值}});}//组件销毁的时候触发@overridevoid dispose() {// TODO: implement disposesuper.dispose();_tabController.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: PreferredSize(preferredSize: Size.fromHeight(40),child: Container(height: 40,child: AppBar(elevation: 0.5,backgroundColor: Colors.white,centerTitle: true,title: TabBar(//只能监听点击事件,不能监听滑动onTap: (value) {},labelStyle: TextStyle(fontSize: 14),isScrollable: true,indicatorColor: Colors.red,labelColor: Colors.red,unselectedLabelColor: Colors.black,indicatorWeight: 2,indicatorPadding: EdgeInsets.all(5),indicatorSize: TabBarIndicatorSize.label,// indicator: BoxDecoration(// color: Colors.blue, borderRadius: BorderRadius.circular(10)),controller: _tabController,tabs: const [Tab(child: Text("热门")),Tab(child: Text("推荐")),Tab(child: Text("视频"))],),),),),body: TabBarView(controller: _tabController,children: const [KeepAliveWrapper(child: Text(("热门")),),KeepAliveWrapper(child: Text(("推荐")),),KeepAliveWrapper(child: Text(("视频")),),],),);}
}
import '../SearchPage.dart';Center(
child: ElevatedButton(onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(builder: (context){
return const SearchPage();
})
);
}, child: const Text("跳转到搜索页面")),
)
Navigator.of(context).push(MaterialPageRoute(builder: (context) {return const SearchPage(title: "搜索页面",);}));
import 'package:flutter/material.dart';class SearchPage extends StatefulWidget {final String title;const SearchPage({super.key, this.title = "默认Search Page"});@overrideState createState() => _SearchPageState();
}class _SearchPageState extends State {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),//获取SearchPage定义的title),body: Center(child: Text("搜索页面"),),);}
}
Navigator.pop(context);
Navigator.of(context).pop();
Navigator.pushNamed(context, "/search");
main.dart
import 'package:flutter/material.dart';
import './pages/tabs.dart';
import './pages/search.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,theme: ThemeData(primarySwatch: Colors.blue),//home: const MyHomePage(),initialRoute: "/",routes: {'/': (contxt) => const MyHomePage(),'/search': (contxt) => const SearchPage(),},);}
}
Navigator.pushNamed(context, '/search', arguments: {"title": "搜索页面",});
main.dart
import 'package:flutter/material.dart';
import './pages/tabs.dart';
import './pages/search.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {//1、定义Map类型的routesMap routes = {'/': (contxt) => const MyHomePage(),'/search': (context, {arguments}) => SearchPage(arguments: arguments),};MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,theme: ThemeData(primarySwatch: Colors.blue),//home: const MyHomePage(),initialRoute: "/",//2、调用onGenerateRoute处理onGenerateRoute: (RouteSettings settings) {// 统一处理final String? name = settings.name;final Function? pageContentBuilder = routes[name];if (pageContentBuilder != null) {if (settings.arguments != null) {final Route route = MaterialPageRoute(builder: (context) =>pageContentBuilder(context, arguments: settings.arguments));return route;} else {final Route route = MaterialPageRoute(builder: (context) => pageContentBuilder(context));return route;}}return null;},);}
}
search.dart
import 'package:flutter/material.dart';class SearchPage extends StatefulWidget {final String title;final Map arguments;const SearchPage({super.key, this.title = "默认Search Page", required this.arguments});@overrideState createState() => _SearchPageState();
}class _SearchPageState extends State {@overridevoid initState() {print(widget.arguments);}@overrideWidget build(BuildContext context) {return Scaffold(floatingActionButton: FloatingActionButton(onPressed: () {Navigator.pop(context);},child: Icon(Icons.back_hand),),appBar: AppBar(title: Text(widget.title), //获取SearchPage定义的title),body: Center(child: Text("搜索页面"),),);}
}
新建routers/routers.dart 配置路由
import 'package:flutter/material.dart';
import '../tabs.dart';
import '../search.dart';final Map routes = {'/': (contxt) => const MyHomePage(),'/search': (context, {arguments}) => SearchPage(arguments: arguments),
};
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(builder: (context) =>pageContentBuilder(context, arguments: settings.arguments));return route;} else {final Route route =MaterialPageRoute(builder: (context) => pageContentBuilder(context));return route;}}return null;
};
main.dart
class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,theme: ThemeData(primarySwatch: Colors.blue),//home: const MyHomePage(),initialRoute: "/",//2、调用onGenerateRoute处理onGenerateRoute: onGenerateRoute);}
}
Navigator.of(context).pushReplacementNamed('/registerSecond');
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) {
return const Tabs();
}), (route) => false);
import ‘package:flutter/cupertino.dart’;
MaterialPageRoute改为CupertinoPageRoute
flutter run

void _alertDialog() async {var result = await showDialog(context: context,builder: (context) {return AlertDialog(title: const Text("提示信息!"),content: const Text("您确定要删除吗?"),actions: [TextButton(child: const Text("取消"),onPressed: () {print("取消");Navigator.pop(context, 'Cancle');},),TextButton(child: const Text("确定"),onPressed: () {print("确定");Navigator.of(context).pop("Ok");// Navigator.pop(context, "Ok");},)],);});print(result);}

void _simpleDialog() async {var result = await showDialog(barrierDismissible: true, //表示点击灰色背景的时候是否消失弹出框context: context,builder: (context) {return SimpleDialog(title: const Text("请选择内容"),children: [SimpleDialogOption(child: const Text("Option A"),onPressed: () {print("Option A");Navigator.pop(context, "A");},),const Divider(),SimpleDialogOption(child: const Text("Option B"),onPressed: () {print("Option B");Navigator.pop(context, "B");},),const Divider(),SimpleDialogOption(child: const Text("Option C"),onPressed: () {print("Option C");Navigator.pop(context, "C");},),],);});print(result);}
_modelBottomSheet() async {var result = await showModalBottomSheet(context: context,builder: (context) {return SizedBox(height: 220,child: Column(children: [ListTile(title: const Text("分享 A"),onTap: () {Navigator.pop(context, "分享 A");},),const Divider(),ListTile(title: const Text("分享 B"),onTap: () {Navigator.pop(context, "分享 B");},),const Divider(),ListTile(title: const Text("分享 C"),onTap: () {Navigator.pop(context, "分享 C");},)],),);});print(result);}
https://pub.dev/packages/fluttertoast

import 'dart:async';
import 'package:flutter/material.dart';// ignore: must_be_immutable
class MyDialog extends Dialog {String title;String content;Function()? onClosed;MyDialog({Key? key,required this.title,required this.onClosed,this.content = ""}): super(key: key);@overrideWidget build(BuildContext context) {return Material(type: MaterialType.transparency,child: Center(child: Container(height: 300,width: 300,color: Colors.white,child: Column(children: [Padding(padding: const EdgeInsets.all(10),child: Stack(children: [Align(alignment: Alignment.center,child: Text(title),),Align(alignment: Alignment.centerRight,child: InkWell(onTap: onClosed,child: const Icon(Icons.close),),)],),),const Divider(),Container(padding: const EdgeInsets.all(10),width: double.infinity,child: Text(content, textAlign: TextAlign.left),)],),)),);}
}
void _myDialog() async {await showDialog(barrierDismissible: true, //表示点击灰色背景的时候是否消失弹出框context: context,builder: (context) {return MyDialog(title: '标题',onClosed: () {print("关闭");Navigator.of(context).pop();},content: "我是一个内容");});}
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,),)],)
import 'package:flutter/material.dart';class MyPageView extends StatefulWidget {const MyPageView({super.key});@overrideState createState() => _MyPageViewState();
}class _MyPageViewState extends State {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("pageview演示"),),body: PageView.builder(scrollDirection: Axis.vertical, // 滑动方向为垂直方向itemBuilder: (BuildContext context, int index) {return MyPage(text: "$index");},itemCount: 10,));}
}class MyPage extends StatefulWidget {final String text;const MyPage({super.key, required this.text});@overrideState createState() => _MyPageState();
}class _MyPageState extends State {@overrideWidget build(BuildContext context) {return Center(child: Text(widget.text, style: Theme.of(context).textTheme.headline1),);}
}
import 'package:flutter/material.dart';class MyPageView extends StatefulWidget {const MyPageView({super.key});@overrideState createState() => _MyPageViewState();
}class _MyPageViewState extends State {final List _list = [];@overridevoid initState() {super.initState();for (var i = 0; i < 10; i++) {_list.add(MyPage(text: "$i"));}}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("pageview演示"),),body: PageView(scrollDirection: Axis.vertical, // 滑动方向为垂直方向onPageChanged: (index) {print(index);print(_list.length);if (index + 2 == _list.length) {setState(() {for (var i = 0; i < 10; i++) {_list.add(MyPage(text: "$i"));}});}},children: _list,));}
}class MyPage extends StatefulWidget {final String text;const MyPage({super.key, required this.text});@overrideState createState() => _MyPageState();
}class _MyPageState extends State {@overrideWidget build(BuildContext context) {return Center(child: Text(widget.text, style: Theme.of(context).textTheme.headline1),);}
}
List.generate(widget.pageList.length, (i) { })
设置 left: 0, right: 0,就会占满一行
Flutter定时器

const timeout = Duration(seconds: 3);
var t=Timer.periodic(timeout, (timer) {
print('afterTimer='+DateTime.now().toString()););
// timer.cancel(); // 取消定时器
});
t.cancel(); // 取消定时器
import 'package:flutter/material.dart';
import './swiper.dart';class MyPageView extends StatefulWidget {const MyPageView({super.key});@overrideState createState() => _MyPageViewState();
}class _MyPageViewState extends State {List pageList = [];@overridevoid initState() {List listData = [{"imageUrl": 'https://www.itying.com/images/flutter/1.png',},{"imageUrl": 'https://www.itying.com/images/flutter/2.png',},{"imageUrl": 'https://www.itying.com/images/flutter/3.png',}];for (int i = 0; i < listData.length; ++i) {pageList.add(PicturePage(url: listData[i]["imageUrl"],));}}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("pageview演示"),),body: SizedBox(height: 200,child: PageView(//scrollDirection: Axis.vertical, // 滑动方向为垂直方向children: [Swiper(pageList: pageList)],),));}
}class MyPage extends StatefulWidget {final String text;const MyPage({super.key, required this.text});@overrideState createState() => _MyPageState();
}class _MyPageState extends State {@overrideWidget build(BuildContext context) {return Center(child: Text(widget.text, style: Theme.of(context).textTheme.headline1),);}
}
import 'package:flutter/material.dart';
import 'dart:async';class Swiper extends StatefulWidget {final double width;final double height;final List pageList;const Swiper({super.key,this.width = double.infinity,this.height = 200,required this.pageList});@overrideState createState() => _SwiperState();
}class _SwiperState extends State {late PageController _pageController;int _currentPageIndex = 0;late Timer timer;@overridevoid initState() {super.initState();_pageController = PageController(initialPage: 0);const timeout = Duration(seconds: 3);timer = Timer.periodic(timeout, (timer) {//跳转_pageController.animateToPage((_currentPageIndex + 1) % (widget.pageList.length),curve: Curves.linear,duration: const Duration(milliseconds: 200));// timer.cancel(); // 取消定时器});}@overridevoid dispose() {super.dispose();timer.cancel();_pageController.dispose();}@overrideWidget build(BuildContext context) {return Stack(children: [SizedBox(width: double.infinity,height: 200,child: PageView.builder(controller: _pageController,onPageChanged: (int index) {setState(() {_currentPageIndex = index % (widget.pageList.length);});},itemCount: 10000,itemBuilder: (context, index) {return widget.pageList[index % (widget.pageList.length)];}),),Positioned(bottom: 10,left: 0,right: 0,child: Row(mainAxisAlignment: MainAxisAlignment.center,children: List.generate(widget.pageList.length, (i) {return Container(margin: const EdgeInsets.fromLTRB(2, 0, 2, 0),width: 10,height: 10,decoration: BoxDecoration(shape: BoxShape.circle,color: _currentPageIndex == i ? Colors.blue : Colors.grey),);}).toList(),),),],);}
}class PicturePage extends StatefulWidget {final String url;final double width;final double height;const PicturePage({super.key,required this.url,this.width = double.infinity,this.height = 200});@overrideState createState() => _PicturePageState();
}class _PicturePageState extends State {@overrideWidget build(BuildContext context) {print(widget.url);return SizedBox(width: widget.width,height: widget.height,child: Image.network(widget.url, fit: BoxFit.cover),);}
}
KeepAliveWrapper(
child: Text((“热门”)),
),
上一篇:Verilog语法