flutter入门
1.windows上搭建flutter开发环境
1.1 安装配置JDK Java Downloads | Oracle
1.2安装android studio Download Android Studio & App Tools - Android Developers (google.cn)
1.3下载配置flutter SDK(Flutter SDK 发布|扑动)
下载解压flutterSDK 将D:\flutter_windows_3.7.1-stable\flutter\bin配置到环境变量Path中
通过flutter doctor查看flutter环境是否配置成功
2.flutter的目录、入口、自定义widget
- android——包含Android特定文件的Android子工程
- build——是运行项目的时候生成的编译文件,即Android和iOS的构建产物
- ios——包含iOS特定文件的iOS子工程
- lib——Flutter应用源文件目录,我们自己写的Dart文件都放进lib文件夹中
- test——测试文件
- pubspec.yaml——管理第三方库及资源的配置文件
3.Container组件
import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: const Text("你好flutter"), ), body: const Column(children: [MyApp(), MyButton()])), )); } //无状态组件 class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return Center( //类似div child: Container( alignment: Alignment.center, //内容显示的方位 margin: const EdgeInsets.fromLTRB(0, 60, 0, 0), width: 200, height: 100, transform: Matrix4.translationValues(40, 0, 0), //位移 // transform: Matrix4.rotationZ(0.2), //旋转 decoration: BoxDecoration( color: Colors.red, //设置背景颜色 border: Border.all( //设置边框 color: Colors.black, width: 2), borderRadius: BorderRadius.circular(10), //配置圆角 boxShadow: const [ //配置阴影 BoxShadow(color: Colors.black, blurRadius: 20) ], //设置渐变 gradient: const LinearGradient(colors: [Colors.red, Colors.yellow])), child: const Text( //通过child设置盒子的内容 "你好flutteree", style: TextStyle(color: Colors.white, fontSize: 20), ), )); } } //自定义按钮 class MyButton extends StatelessWidget { const MyButton({super.key}); @override Widget build(BuildContext context) { return Container( alignment: Alignment.center, width: 200, height: 40, margin: const EdgeInsets.fromLTRB(0, 20, 0, 0), padding: const EdgeInsets.all(0), decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(20)), child: const Text( "按钮", style: TextStyle(color: Colors.white, fontSize: 20), ), ); } }
4.text组件
import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: const Text("你好flutter"), ), body: const Column(children: [ MyText()])), )); } class MyText extends StatelessWidget { const MyText({super.key}); @override Widget build(BuildContext context) { return Container( width: 200, height: 200, decoration: const BoxDecoration(color: Colors.yellow), child: const Text( "你好flutter恶法士大夫士大夫首发式地方得到的赌东道", textAlign: TextAlign.left, maxLines: 1, //显示的行数 overflow: TextOverflow.ellipsis, //超出显示... style: TextStyle( fontSize: 20, fontWeight: FontWeight.w600, letterSpacing: 5), //设置字体样式 ), ); } }
5.图片组件Image
import 'package:flutter/material.dart'; import 'package:flutter/services.dart';
// 图片的属性const Image({
...
this.width, //图片的宽
this.height, //图片高度
this.color, //图片的混合色值
this.colorBlendMode, //混合模式
this.fit,//缩放模式
this.alignment = Alignment.center, //对齐方式
this.repeat = ImageRepeat.noRepeat, //重复方式
...
})
//1.Image.network加载远程图片 void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: const Text("你好flutter"), ), body: const Column( children: [ MyApp(), Curculer(), SizedBox( height: 20, ), ClipImage(), SizedBox( height: 20, ), LocalImg() ], )))); }
//无状态组件 class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return Center( child: Container( height: 150, width: 150, margin: const EdgeInsets.fromLTRB(0, 0, 0, 20), decoration: const BoxDecoration(color: Colors.yellow), child: Image.network( //加载远程图片 "https://img0.baidu.com/it/u=2028084904,3939052004&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", // scale: 4, //缩小图片 // fit: BoxFit.cover, //对图片进行剪裁 // repeat: ImageRepeat.repeatY, //平铺 ), ), ); } } //实现圆形图片 class Curculer extends StatelessWidget { const Curculer({super.key}); @override Widget build(BuildContext context) { return Container( height: 150, width: 150, decoration: BoxDecoration( color: Colors.pink, borderRadius: BorderRadius.circular(75), image: const DecorationImage( image: NetworkImage( "https://img2.baidu.com/it/u=3217543765,3223180824&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=750", ), fit: BoxFit.cover)), ); } } //实现圆形图片使用ClipOval class ClipImage extends StatelessWidget { const ClipImage({super.key}); @override Widget build(BuildContext context) { return ClipOval( child: Image.network( "https://img1.baidu.com/it/u=105002249,3897918256&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281", width: 150, height: 150, fit: BoxFit.cover, ), ); } } //2.加载本地图片Image.asset class LocalImg extends StatelessWidget { const LocalImg({super.key}); @override Widget build(BuildContext context) { return Container( height: 150, width: 150, decoration: const BoxDecoration(color: Colors.yellow), child: Image.asset( "images/logo.png", fit: BoxFit.cover, ), ); } }
//在pusspec.yaml配置:
6.自带图标组件及自定义图标
import 'package:flutter/material.dart'; import './myIcon.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyFontIcon(), ), ); } } //1.内置图标 class MyFontIcon extends StatelessWidget { const MyFontIcon({super.key}); @override Widget build(BuildContext context) { return const Column( children: [ SizedBox( height: 20, ), Icon( Icons.home, size: 40, color: Colors.red, ), SizedBox( height: 20, ), Icon(Icons.search), SizedBox( height: 20, ), Icon(Icons.person), SizedBox( height: 20, ), Icon( Icons.category, size: 30, color: Colors.yellow, ), SizedBox( height: 20, ), Icon( MyIcon.cart, size: 20, ), Icon(MyIcon.book) //2.自定义图标 ], ); } }
7.ListView列表组件
ListView
是最常用的可滚动组件之一,它可以沿一个方向线性排布所有子组件
import 'package:flutter/material.dart'; import './myIcon.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyFontIcon(), ), ); } } //1.列表组件 class MyFontIcon extends StatelessWidget { const MyFontIcon({super.key}); @override Widget build(BuildContext context) { return ListView( children: const <Widget>[ ListTile( title: Text("我是一个列表"), ), Divider(), ListTile( title: Text("我是一个列表"), ), Divider(), ListTile( title: Text("我是一个列表"), ), Divider(), ListTile( title: Text("我是一个列表"), ), Divider(), ListTile( title: Text("我是一个列表"), ), Divider(), ListTile( title: Text("我是一个列表"), ), Divider(), ListTile( title: Text("我是一个列表"), ), Divider(), ListTile( title: Text("我是一个列表"), ), Divider( color: Colors.black, ), ListTile( title: Text("我是一个列表"), ), Divider( color: Colors.black, ), ListTile( title: Text("我是一个列表"), ), Divider(), ListTile( title: Text("我是一个列表"), ), ], ); } }
import 'package:flutter/material.dart'; import './myIcon.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyFontIcon(), ), ); } } //1.竖向列表组件 class MyFontIcon extends StatelessWidget { const MyFontIcon({super.key}); @override Widget build(BuildContext context) { return ListView( children: const <Widget>[ ListTile( leading: Icon(Icons.home), //配置左边 title: Text("首页"), trailing: Icon(Icons.chevron_right_sharp), //配置右边 ), Divider( color: Colors.grey, ), ListTile( leading: Icon( Icons.assessment, color: Colors.red, ), title: Text("订单"), ), Divider( color: Colors.grey, ), ListTile( leading: Icon( Icons.payments, color: Colors.green, ), title: Text("待付款"), ), Divider( color: Colors.grey, ), ListTile( leading: Icon( Icons.favorite, color: Colors.lightGreen, ), title: Text("我的收藏"), ), Divider( color: Colors.grey, ), ListTile( leading: Icon( Icons.people, color: Colors.black12, ), title: Text("在线客户"), trailing: Icon(Icons.chevron_right_sharp), ), Divider( color: Colors.grey, ), ], ); } }
import 'package:flutter/material.dart'; import './myIcon.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyFontIcon(), ), ); } } //1.横向列表列表组件 class MyFontIcon extends StatelessWidget { const MyFontIcon({super.key}); @override Widget build(BuildContext context) { return SizedBox( height: 120, child: ListView( scrollDirection: Axis.horizontal, //设置水平列表 padding: const EdgeInsets.all(20), children: [ Container( //垂直列表宽度自适应,设置宽度没有用,水平列表高度自适应 width: 150, decoration: const BoxDecoration(color: Colors.red), ), Container( width: 150, decoration: const BoxDecoration(color: Colors.pink), ), Container( width: 150, decoration: const BoxDecoration(color: Colors.yellow), ), Container( width: 150, decoration: const BoxDecoration(color: Colors.black), ), Container( width: 150, decoration: const BoxDecoration(color: Colors.yellow), ), Container( width: 150, decoration: const BoxDecoration(color: Colors.black), ), ], )); } }
// ignore_for_file: use_key_in_widget_constructors import 'package:flutter/material.dart'; import './res/data.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyList(), ), ); } } // //1.动态列表map // class MyList extends StatelessWidget { // const MyList({super.key}); // List<Widget> _initData() { // var list = listData.map((item) { // return ListTile( // leading: Image.network("${item['imgUrl']}"), // title: Text("${item['title']}"), // subtitle: Text("${item['author']}"), // ); // }); // return list.toList(); // } // @override // Widget build(BuildContext context) { // return ListView( // children: _initData(), // ); // } // } //2.动态列表listBUild class MyList extends StatelessWidget { const MyList({super.key}); @override Widget build(BuildContext context) { return ListView.builder( itemCount: listData.length, //数组的长度 itemBuilder: (context, index) { return ListTile( leading: Image.network("${listData[index]["imgUrl"]}"), title: Text("${listData[index]["title"]}"), subtitle: Text("${listData[index]["author"]}"), ); }); } }
8.网格布局gridView
import 'package:flutter/material.dart'; import './res/data.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyList(), ), ); } } // //1.网格布局count // class MyList extends StatelessWidget { // const MyList({super.key}); // List<Widget> _initData() { // var list = listData.map((item) { // return Container( // decoration: BoxDecoration(border: Border.all(color: Colors.black26)), // child: Column(children: [ // Image.network("${item['imgUrl']}"), // const SizedBox( // height: 10, // ), // Text( // "${item['title']}", // style: const TextStyle(fontSize: 16), // ) // ]), // ); // }); // return list.toList(); // } // @override // Widget build(BuildContext context) { // return GridView.count( // padding: const EdgeInsets.all(10), // crossAxisCount: 3, //一行显示的数量 // mainAxisSpacing: 10, //垂直子元素之间的间距 // crossAxisSpacing: 10, //水平子元素之间的间距 // childAspectRatio: 1.1, //子元素宽高比 // children: _initData()); // } // } // //2.网格布局extent // class MyList extends StatelessWidget { // const MyList({super.key}); // List<Widget> _initData() { // var list = listData.map((item) { // return Container( // decoration: BoxDecoration(border: Border.all(color: Colors.black26)), // child: Column(children: [ // Image.network("${item['imgUrl']}"), // const SizedBox( // height: 10, // ), // Text( // "${item['title']}", // style: const TextStyle(fontSize: 16), // ) // ]), // ); // }); // return list.toList(); // } // @override // Widget build(BuildContext context) { // return GridView.extent( // padding: const EdgeInsets.all(10), // maxCrossAxisExtent: 180, //子元素在横轴上的最大长度 // mainAxisSpacing: 10, //垂直子元素之间的间距 // crossAxisSpacing: 10, //水平子元素之间的间距 // childAspectRatio: 1.1, //子元素宽高比 // children: _initData()); // } // } //3.网格布局GridView.builder SliverGridDelegateWithFixedCrossAxisCount // class MyList extends StatelessWidget { // const MyList({super.key}); // Widget _initData(context, index) { // return Container( // decoration: BoxDecoration(border: Border.all(color: Colors.black26)), // child: Column(children: [ // Image.network("${listData[index]['imgUrl']}"), // const SizedBox( // height: 10, // ), // Text( // "${listData[index]['title']}", // style: const TextStyle(fontSize: 16), // ) // ]), // ); // } // @override // Widget build(BuildContext context) { // return GridView.builder( // padding: const EdgeInsets.all(10), // itemCount: listData.length, // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( // crossAxisCount: 2, //子元素在横轴上的最大长度 // mainAxisSpacing: 10, //垂直子元素之间的间距 // crossAxisSpacing: 10, //水平子元素之间的间距 // childAspectRatio: 1.1, //子元素宽高比 // ), // itemBuilder: _initData, // ); // } // } //4.网格布局GridView.builderSliverGridDelegateWithMaxCrossAxisExtent class MyList extends StatelessWidget { const MyList({super.key}); Widget _initData(context, index) { return Container( decoration: BoxDecoration(border: Border.all(color: Colors.black26)), child: Column(children: [ Image.network("${listData[index]['imgUrl']}"), const SizedBox( height: 10, ), Text( "${listData[index]['title']}", style: const TextStyle(fontSize: 16), ) ]), ); } @override Widget build(BuildContext context) { return GridView.builder( padding: const EdgeInsets.all(10), itemCount: listData.length, gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 120, //子元素在横轴上的最大长度 mainAxisSpacing: 10, //垂直子元素之间的间距 crossAxisSpacing: 10, //水平子元素之间的间距 childAspectRatio: 1.1, //子元素宽高比 ), itemBuilder: _initData, ); } }
9.行和列布局组件
所谓线性布局,即指沿水平或垂直方向排列子组件。Flutter 中通过Row
和Column
来实现线性布局
import 'package:flutter/material.dart'; import './res/data.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyList(), ), ); } } // //1.行组件Row // class MyList extends StatelessWidget { // const MyList({super.key}); // @override // Widget build(BuildContext context) { // return Container( // width: double.infinity, //设置无穷大,占满屏幕或上个容器 // height: double.infinity, // child: Row( // //行内组件,宽度自适应 // mainAxisAlignment: MainAxisAlignment.spaceBetween, //水平空间内对齐方式 // crossAxisAlignment: // CrossAxisAlignment.center, //表示子组件在纵轴方向的对齐方式,相对于父元素 // children: [ // IconContainer(Icons.home), // IconContainer( // Icons.carpenter_sharp, // color: Colors.black12, // ), // IconContainer( // Icons.search, // color: Colors.yellow, // ), // ], // )); // } // } //2.列组件Colnum class MyList extends StatelessWidget { const MyList({super.key}); @override Widget build(BuildContext context) { return Container( width: double.infinity, //设置无穷大,占满屏幕或上个容器 height: double.infinity, child: Column( //行内组件,高度自适应 mainAxisAlignment: MainAxisAlignment.spaceBetween, //垂直空间内对齐方式 crossAxisAlignment: CrossAxisAlignment.start, //表示子组件在横轴方向的对齐方式,相对于父元素 children: [ IconContainer(Icons.home), IconContainer( Icons.carpenter_sharp, color: Colors.black12, ), IconContainer( Icons.search, color: Colors.yellow, ), ], )); } } //自定义图片容器 // ignore: must_be_immutable class IconContainer extends StatelessWidget { IconData icon; Color color; IconContainer(this.icon, {super.key, this.color = Colors.red}); @override Widget build(BuildContext context) { return Container( height: 120, width: 120, color: color, child: Icon( icon, color: Colors.white, size: 28, ), ); } }
10.flex布局
弹性布局允许子组件按照一定比例来分配父容器空间。弹性布局的概念在其他UI系统中也都存在,如 H5 中的弹性盒子布局,Android中 的FlexboxLayout
等。Flutter 中的弹性布局主要通过Flex
和Expanded
来配合实现。
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyList(), ), ); } } //1.flex布局 class MyList extends StatelessWidget { const MyList({super.key}); @override Widget build(BuildContext context) { return Flex( direction: Axis.horizontal, //行内组件,宽度自适应 children: [ Expanded( flex: 1, child: IconContainer(Icons.home), //元素设置宽度没有效果 ), Expanded( flex: 2, child: IconContainer( Icons.search, color: Colors.yellow, ), ) ], ); } } //自定义图片容器 // ignore: must_be_immutable class IconContainer extends StatelessWidget { IconData icon; Color color; IconContainer(this.icon, {super.key, this.color = Colors.red}); @override Widget build(BuildContext context) { return Container( height: 120, width: 120, color: color, child: Icon( icon, color: Colors.white, size: 28, ), ); } }
11.stack、positioned、align组件
层叠布局和 Web 中的绝对定位、Android 中的 Frame 布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。层叠布局允许子组件按照代码中声明的顺序堆叠起来。Flutter中使用Stack
和Positioned
这两个组件来配合实现绝对定位。Stack
允许子组件堆叠,而Positioned
用于根据Stack
的四个角来确定子组件的位置
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyList(), ), ); } } //1.Stack组件 // class MyList extends StatelessWidget { // const MyList({super.key}); // @override // Widget build(BuildContext context) { // return Stack( // //堆叠组件 // // alignment: Alignment.center, // children: [ // Container( // height: 300, // width: 300, // color: Colors.pink, // ), // Container( // height: 150, // width: 150, // color: Colors.red, // ), // const Text('你好flutter') // ], // ); // } // } //2.Positioned定位组件 // class MyList extends StatelessWidget { // const MyList({super.key}); // @override // Widget build(BuildContext context) { // return Container( // height: 400, // width: 300, // color: Colors.yellow, // child: Stack( // children: [ // Positioned( // //与Stack一起使用,相对于外部容器,没有外部容器相对于屏幕 // left: 0, // bottom: 0, // child: Container( // height: 200, // width: 200, // color: Colors.pink, // ), // ), // const Positioned(right: 0, child: Text('你好flutter')) // ], // )); // } // } // //3.Positioned实现浮动导航 // class MyList extends StatelessWidget { // const MyList({super.key}); // @override // Widget build(BuildContext context) { // final size = MediaQuery.of(context).size; //获取屏幕的宽高 // return Stack( // children: [ // ListView( // padding: const EdgeInsets.only(bottom: 44), // children: const [ // ListTile( // title: Text("我是一个列表1"), // ), // ListTile( // title: Text("我是一个列表2"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表"), // ), // ListTile( // title: Text("我是一个列表t"), // ), // ], // ), // Positioned( // bottom: 0, // left: 0, // width: size.width, //设置子元素的宽高 // child: Container( // alignment: Alignment.center, // height: 44, // color: Colors.grey, // child: const Text("二级导航"), // )) // ], // ); // } // } //4.Align组件 class MyList extends StatelessWidget { const MyList({super.key}); @override Widget build(BuildContext context) { return Container( width: 300, height: 300, color: Colors.red, child: const Align( alignment: Alignment.center, child: Text("你好flutter"), ), ); } }
12.card组件
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.yellow), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyList(), ), ); } } //1.card组件 class MyList extends StatelessWidget { const MyList({super.key}); @override Widget build(BuildContext context) { return ListView( children: [ Card( margin: const EdgeInsets.all(10), //间距 elevation: 20, //设置阴影的深度 shape: RoundedRectangleBorder( //阴影的效果 borderRadius: BorderRadius.circular(20), ), child: const Column(children: [ ListTile( leading: CircleAvatar( //圆形图片 radius: 30, //设置大小 backgroundImage: NetworkImage( "https://img2.baidu.com/it/u=2929594913,1208145904&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400"), ), title: Text("张三"), subtitle: Text("高级工程师"), ), Divider(), ListTile( title: Text("电话:123234324"), ), ListTile( title: Text("地址:xxx"), ) ]), ), Card( margin: const EdgeInsets.all(10), //间距 elevation: 20, //设置阴影的深度 shape: RoundedRectangleBorder( //阴影的效果 borderRadius: BorderRadius.circular(20), ), child: const Column(children: [ ListTile( leading: CircleAvatar( backgroundImage: NetworkImage( "https://inews.gtimg.com/newsapp_bt/0/14043621628/641"), ), title: Text("李四"), subtitle: Text("高级工程师"), ), Divider(), ListTile( title: Text("电话:123234324"), ), ListTile( title: Text("地址:xxx"), ) ]), ), ], ); } }
12.按钮组件
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.blue), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const Column(children: [ MyElevatedButton(), MyTextButton(), MyOutLineButton(), MyIconButton(), MyIconButton1(), MyBigButton() ]), ), ); } } //1.ElevatedButton"漂浮"按钮 class MyElevatedButton extends StatelessWidget { const MyElevatedButton({super.key}); @override Widget build(BuildContext context) { return ElevatedButton( style: //修改按钮的样式 ButtonStyle( backgroundColor: MaterialStateProperty.all( //背景颜色 Colors.red, ), foregroundColor: MaterialStateProperty.all(Colors.black)), //文字颜色 child: const Text( "normal", ), onPressed: () {}, ); } } //2.MyTextButton默认背景透明并不带阴影。按下后,会有背景色 class MyTextButton extends StatelessWidget { const MyTextButton({super.key}); @override Widget build(BuildContext context) { return TextButton( child: const Text( "normal", ), onPressed: () {}, ); } } //4.边框按钮 class MyOutLineButton extends StatelessWidget { const MyOutLineButton({super.key}); @override Widget build(BuildContext context) { return OutlinedButton( style: ButtonStyle( side: MaterialStateProperty.all( const BorderSide(width: 1, color: Colors.black))), onPressed: null, child: const Text( "边框的按钮", ), ); } } //5.IconButton是一个可点击的Icon。不包括文字,默认没有背景,点击后会出现背景 class MyIconButton extends StatelessWidget { const MyIconButton({super.key}); @override Widget build(BuildContext context) { return IconButton( icon: const Icon(Icons.thumb_up), onPressed: () {}, ); } } //6. 带图标的按钮 class MyIconButton1 extends StatelessWidget { const MyIconButton1({super.key}); @override Widget build(BuildContext context) { return Column( children: [ ElevatedButton.icon( icon: const Icon(Icons.send), label: const Text("发送"), onPressed: () => {}, ), TextButton.icon( icon: const Icon(Icons.info), label: const Text("详情"), onPressed: () => {}, ), ], ); } } //7.设置按钮宽高 class MyBigButton extends StatelessWidget { const MyBigButton({super.key}); @override Widget build(BuildContext context) { return Container( height: 50, width: 150, child: ElevatedButton(onPressed: () => {}, child: const Text("大按钮")), ); } }
13.进度指示器组件
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.blue), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const Column(children: [MyLineProgress(), MyCircularProgress()]), ), ); } } //1.LinearProgressIndicator是一个线性、条状的进度条 class MyLineProgress extends StatelessWidget { const MyLineProgress({super.key}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.only(top: 20), child: LinearProgressIndicator( minHeight: 30, //进度条的宽高 backgroundColor: Colors.grey[200], //指示器的背景色 valueColor: const AlwaysStoppedAnimation(Colors.blue), //指示器的进度条颜色 value: .8, //表示当前的进度,取值范围为[0,1] ), ); } } //2.CircularProgressIndicator圆形进度条 class MyCircularProgress extends StatelessWidget { const MyCircularProgress({super.key}); @override Widget build(BuildContext context) { return Container( height: 100, width: 100, padding: const EdgeInsets.only(top: 20), child: CircularProgressIndicator( strokeWidth: 6, backgroundColor: Colors.grey[200], valueColor: const AlwaysStoppedAnimation(Colors.blue), value: .5, ), ); } }
14.Wrap组件
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.blue), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyPage(), ), ); } } //1. class MyPage extends StatelessWidget { const MyPage({super.key}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(10), child: Wrap( //一行放不下就换行 spacing: 15, //水平间距 runSpacing: 20, //垂直间距 // direction: Axis.vertical, //垂直排列 children: [ Button( "第1季", onPressed: () => {}, ), Button("第2季", onPressed: () => {}), Button("第3季", onPressed: () => {}), Button("第4季", onPressed: () => {}), Button("第5季", onPressed: () => {}), Button("第6季", onPressed: () => {}), Button("第7季", onPressed: () => {}), Button("第8季", onPressed: () => {}), Button("第9季", onPressed: () => {}), ]), ); } } class Button extends StatelessWidget { String text; void Function()? onPressed; Button(this.text, {super.key, required this.onPressed}); @override Widget build(BuildContext context) { return ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all( const Color.fromARGB(255, 248, 241, 241)), foregroundColor: MaterialStateProperty.all(Colors.black26)), onPressed: () => {}, child: Text(text)); } }
15.综合练习
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.blue), home: Scaffold( appBar: AppBar( title: const Text("FLutter app"), ), body: const MyPage(), ), ); } } class MyPage extends StatelessWidget { const MyPage({super.key}); @override Widget build(BuildContext context) { return ListView( padding: const EdgeInsets.all(10), children: [ Row( children: [ Text( "热搜", style: Theme.of(context).textTheme.titleLarge, ), ], ), Divider(), Wrap( spacing: 10, runSpacing: 10, children: [ Button("女装", onPressed: () => {}), Button("男装", onPressed: () => {}), Button("笔记本电脑", onPressed: () => {}), Button("女装22", onPressed: () => {}), Button("童装", onPressed: () => {}), Button("家电", onPressed: () => {}), Button("电视", onPressed: () => {}), ], ), const SizedBox( height: 20, ), Row( children: [ Text( "历史记录", style: Theme.of(context).textTheme.titleLarge, ), ], ), const Divider(), const SizedBox( height: 20, ), Row( children: [ Text( "笔记本", style: Theme.of(context).textTheme.titleLarge, ), ], ), const Divider(), const SizedBox( height: 40, ), OutlinedButton.icon( 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}); @override Widget build(BuildContext context) { return ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all( const Color.fromARGB(255, 248, 241, 241)), foregroundColor: MaterialStateProperty.all(Colors.black26)), onPressed: () => {}, child: Text(text)); } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 【.NET】调用本地 Deepseek 模型