Flutter语言(学习网站:Flutter教程 - Flutter中文网 (flutterchina.club)) flutter的下载安装:
注意 国内访问flutter可能会受限制,可下载国内镜像
PUB_HOSTED_URL https://pub.flutter-io.cn FLUTTER_STORAGE_BASE_URLhttps://storage.flutter-io.cn安装
1、电脑配置JDK(下载jdk,配置jdk )
2、下载安装Android studio
3、下载配置flutter sdk(flutter -v检验是否配置成功)
4、配置flutter国内镜像
5、输入flutter doctor 命令检测环境是否配置成功
(如果出现“!",命令行输入 flutter doctor --android-licenses)
6、Android studio 安装flutter 插件(config->Plugins->flutter)
7、创建项目(第一次创建时间非常长,可能有十几分钟)
报错(下载失败)——点击File->Sync Project With Gradle Files 重新下载Gradle。
Flutter Android 真机调试 1、必备条件:? 准备Android 手机 ;手机、电脑开启调试模式;数据线吧手机电脑相连;手机对应的sdk版本必须安装()
虚拟机调试(模拟器和自带,自带的模拟器较慢安装较麻烦,推荐第三方模拟器)
在Vscode中开发运行Flutter应用1、安装flutter插件、flutter widget snippets插件
2、vscode连不上模拟器的解决方案 :
? cd到模拟器D:xxxxx\bin目录下 运行 nox_adb.exe connect 127.0.01:62001
3、运行flutter项目;r键:点击后热加载,也算是重新加载
? p键:显示网格,可以较好的掌握布局情况,
? o键:切换Android 和ios的预览模式
一、Flutter目录结构介绍、入口、自定义Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件 1.flutter目录结构介绍[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D5q8zPH0-1640866944947)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211016195511058.png)]
build运行项目生成的编译目录,libflutter相关代码,自己放置资源(自己编写的代码),pubspec.yaml项目配置文件(配置项目名称,项目依赖等,一般存放第三方库的依赖)
2、flutter 入口文件、入口方法每个flutter项目里面的lib目录里面都有一个main.dart,这个文件就是flutter的入口文件。
main方法是dart的入口方法,runApp方法 是flutter提供的入口方法,可以调用flutter提供的组件,myApp是自定义的一个组件,flutter所有的组件都是类。
void main() { runApp(new Center(//实例化时new可以省略 child: new Text( '你好Fluter', textDirection: TextDirection.ltr, ))); }实现一些简单的输出
自定义组件(flutter自定义组件就是一个类,这个类需要继承StaelessWidget/StateWidget 抽象类)
? StatelessWidget是无状态组件,状态不可变的widget
? StatefulWidget是有状态组件,持有的状态可能在widget生命周期改变
//自定义组件 import 'package:flutter/material.dart'; void main() { runApp(Myapp()); } //自定义组件 class Myapp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center( //实例化时new可以省略 child: Text( '你好Fluter 我是小栗子', textDirection: TextDirection.ltr, )); } } 3、用MaterialApp和Scaffold两个组装饰AppMaterialApp封装了应用程序实现Material Design 所需要的一些Widget,一般作为顶层widget使用,常用的属性:home(主页)title(标题)color(颜色) theme(主题) routes(路由)
Scaffold的几个属性:
appBar-显示在界面顶部的一个AppBar
body-当前页面所显示的主要内容Widget
drawer-抽屉菜单控制
import 'package:flutter/material.dart'; void main() { runApp(Myapp()); } //自定义组件 class Myapp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Flutter'), ), body: HomeContent(), ), theme: ThemeData(primaryColor: Colors.pink), ); } } class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center( //实例化时new可以省略 child: Text( '你好Fluter 我是小栗子', textDirection: TextDirection.ltr, style: TextStyle( fontSize: 40.0, //和数字有关的都是double类型的。 color: Colors.pink, //或者 color:Colors.fromRGBO(224,233,214,0.5) ), )); } }示例
二、flutter Container组件、Text组件详解Container容器组件,相当于view,div,可以设置颜色
import 'package:flutter/material.dart'; void main() { runApp(Myapp()); } //自定义组件 class Myapp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Flutter'), ), body: HomeContent(), ), theme: ThemeData(primaryColor: Colors.purple.shade100)); } } class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center( //实例化时new可以省略 child: Container( //child子元素 child: Text( '小栗子', textAlign: TextAlign.center, style: TextStyle( fontSize: 18.0, fontStyle: FontStyle.italic, decoration: TextDecoration.lineThrough, letterSpacing: 4.0, //字间距 ), //设置字体属性 overflow: TextOverflow.ellipsis, //超出行的部分省略 maxLines: 1, textScaleFactor: 2, //字体放大两倍 ), height: 300.0, width: 300.0, decoration: BoxDecoration( //背景颜色 color: Colors.pink.shade50, border: Border.all( color: Colors.pink.shade100, width: 2.0, //线的宽度 ), borderRadius: BorderRadius.all( Radius.circular(15.0), ), ), // padding: EdgeInsets.all(50), //四个边距一样 //padding: EdgeInsets.fromLTRB(10, 20, 30, 30)), //transform: Matrix4.translationValues(1, 0, 0), alignment: Alignment.bottomLeft, //改变元素的位置 ) //元素倾斜旋转 ); } } 三、flutter 图片组件image组件有很多构造函数,
Image.asset ,本地图片
Image.network 远程图片
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center( child: Container( child: Image.network( "", alignment: Alignment.bottomLeft, // fit: BoxFit.cover, //fit属性控制图片的拉伸和挤压 repeat: ImageRepeat.repeatX, //图片的平铺 ), width: 200, height: 200, decoration: BoxDecoration(color: Colors.yellow), )); } }flutter实现圆角和圆形图片
用Container实现:
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center( child: Container( width: 200, height: 200, decoration: BoxDecoration( color: Colors.yellow, // borderRadius: BorderRadius.all( // Radius.circular(100), // ) borderRadius: BorderRadius.circular(100), image:DecorationImage( image: NetworkImage(""), fit: BoxFit.cover )), )); } }用ClipOval组件实现
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center( child: ClipOval( child: Image.network("", height: 100, width: 100, fit: BoxFit.cover), ), ); } } Flitter 引入本地图片、在根目录新建文件夹(images)-》新建文件夹(2.0x,3.0x)->打开pubspec.yaml声明以下添加的图片文件,配置对
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jk1SFcvE-1640866944952)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211017114049919.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V4oB5hfl-1640866944955)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211017114308757.png)]
在代码中使用
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center(child: Container(child: Image.asset("images/2.0x/2.jpg"))); } } Flutter ListVew 基础列表组件、水平列表组件、图标组件列表参数:scrollDirection leix:Axis 说明:Axis.horizontal水平列表
padding ,resolve.children(列表元素)
ListView一般配合ListTilte使用,可以加图片和图标,形成图文列表
垂直列表
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return ListView( padding: EdgeInsets.all(10), children: <Widget>[ //返回Widget的数组 ListTile( leading: Icon( Icons.settings, color: Colors.pink, size: 30, ), //前面加图标 title: Text('hhhhh五哈'), subtitle: Text('hhhhhhhhgffnfn hjyygfhhhhhhhhh'), //二级标题 trailing: Icon(Icons.ac_unit_rounded), //后面加图标 ), ListTile( leading: Icon( Icons.home, color: Colors.pink, ), //加图标 title: Text('hhhhh五哈'), subtitle: Text('hhhhhhhhgffnfn hjyygfhhhhhhhhh'), //二级标题 ), ListTile( leading: Image.network( "https://img.ivsky.com/img/tupian/t/201910/05/daoying.jpg", height: 40, width: 40, ), //加图片 title: Text('hhhhh五哈'), subtitle: Text('hhhhhhhhgffnfn hjyygfhhhhhhhhh'), //二级标题 ), ], ); } } class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return ListView( padding: EdgeInsets.all(10), children: <Widget>[ Image.network( "https://img.ivsky.com/img/tupian/t/201910/05/daoying.jpg"), Container( child: Text('我是一个标题', textAlign: TextAlign.center, style: TextStyle(fontSize: 20)), height: 20, ), Image.network( "https://img.ivsky.com/img/tupian/t/201910/05/daoying.jpg"), Image.network( "https://img.ivsky.com/img/tupian/t/201910/05/daoying.jpg"), Image.network( "https://img.ivsky.com/img/tupian/t/201910/05/daoying.jpg"), ], ); } }水平列表
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Container( height: 180, child: ListView( scrollDirection: Axis.horizontal, children: <Widget>[ Container( width: 180, height: 180, color: Colors.pink.shade50, ), Container( width: 180, height: 180, child: ListView( children: <Widget>[ Image.network( "https://img.ivsky.com/img/tupian/t/201910/05/daoying.jpg"), Text('图片'), ], ), color: Colors.pink.shade100, ), Container( width: 180, height: 180, color: Colors.pink.shade400, ), Container( width: 180, height: 180, color: Colors.pink.shade200, ) ], )); } } Flutter ListView 列表组件、动态列表动态列表(循环)
class HomeContent extends StatelessWidget { //自定义方法 List<Widget> _getData() { List<Widget> list = []; for (var i = 0; i < 10; i++) { list.add(ListTile( title: Text("$i个糖炒栗子"), )); } return list; // return [ // ListTile(title: Text('我是一个列表')), // ListTile(title: Text('我是一个列表')), // ListTile(title: Text('我是一个列表')), // ListTile(title: Text('我是一个列表')), // ]; } @override Widget build(BuildContext context) { // TODO: implement build return ListView( children: this._getData(), ); } }用list view.builder实现循环遍历
class HomeContent extends StatelessWidget { List list = []; HomeContent() { for (var i = 0; i < 10; i++) { this.list.add(ListTile( title: Text("$i个糖炒栗子"), )); } } @override Widget build(BuildContext context) { // TODO: implement build return ListView.builder( itemCount: this.list.length, //长度 itemBuilder: (context, index) { return this.list[index]; }, ); } } Flutter GridView组件 以及动态GridView(网格布局)1.GridView.count实现网格布局
class HomeContent extends StatelessWidget { List<Widget> _getData() { List<Widget> list = []; for (var i = 0; i < 20; i++) { list.add(Container( alignment: Alignment.center, color: Colors.pink.shade50, child: Text( 'xiaozili', style: TextStyle(color: Colors.white, fontSize: 20), ), )); } return list; } @override Widget build(BuildContext context) { // TODO: implement build return GridView.count(//实现网格布局 crossAxisSpacing: 20.0, //水平之间的距离 mainAxisSpacing: 20.0, //垂直之间的距离 crossAxisCount: 3, childAspectRatio: 0.7, //宽度和高度的比例 children: this._getData(), padding: EdgeInsets.all(10), //<Widget>[ // Text('eeeee'), // Text('eeeee'), // Text('eeeee'), // Text('eeeee'), // Text('eeeee'), // Text('eeeee'), // ], ); } }GridView.builder实现网格布局跟ListView.builder类似,配置间距参数,需要gridDelegate: SliverGridDelegateWithFixedCrossAxisCount()
Flutter 页面布局 Padding Row Column Expanded组件详解padding组件:很多widget组件没有padding属性,可以使用padding组件来处理
水平布局组件Row:
return Row( mainAxisAlignment: MainAxisAlignment.center, //主轴 crossAxisAlignment: CrossAxisAlignment.end, //次轴 children: <Widget>[ IconCotainer( Icons.search, size: 40, color: Colors.red, ), IconCotainer( Icons.home, size: 40, color: Colors.black, ), IconCotainer( Icons.settings, size: 40, color: Colors.pink, ) ], );垂直布局组件:Column
Flutter Expanded 类似Web中的Flex布局Expanded可以在Row和Column布局中使用
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Expanded(flex: 1, child: Text('xxx')), Expanded(flex: 2, child: Text('xxx')), Expanded(flex: 1, child: Text('xxx')), ], ); } } Flutter 页面布局 Stack层叠组件 Stack 与Align Stack 与Positioned 实现定位布局Stack组件属性:alignment children
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Stack( //元素堆积重叠 alignment: Alignment.center, //让里面所有的元素居中 children: <Widget>[ Container( height: 400, width: 300, color: Colors.red, ), Text('hello'), ], ), ); } } class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Stack( //元素堆积重叠 alignment: Alignment(-1, 0), //调整元素在容器的任意位置 children: <Widget>[ Container( height: 400, width: 300, color: Colors.red, ), Text('hello'), ], ), ); } }Stack结合Align使用:
positioned:top ,right等
AspectRatio,Card卡片组件AspectRatio是调整子元素child的宽高比
Card卡片组件块,内容可由大多数类型的Widget构成,Card具有圆角和阴影。
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: 200, child: ListView( children: <Widget>[ Card( margin: EdgeInsets.all(10), child: Column( children: <Widget>[ ListTile( title: Text( '张三', style: TextStyle(fontSize: 23), ), subtitle: Text('高级工程师'), ), ListTile( title: Text( "1234567890", ), ), ListTile( title: Text( "xxxxxx", ), ), ], ), ) ], )); } }ClipOver,
CircleAvatar专门处理头像的,
页面布局Wrap组件可以实现流布局,单行的wrap和row表现一致,wrap多行时,maxAxis上空间不足时,则向crossAxis上去扩展显示。
RaisedButton定义一个按钮(vscode不用了,用ElevatedButton代替) FluttrfulWidget有状态组件、页面上绑定数据、改变页面数据statefulwidget是状态组件,持有的状态可能在widget生命周期改变,想改变页面数据可能会用到statefulwidget
实现点击按钮,文本文字变化
import 'package:flutter/material.dart'; void main() { runApp(Myapp()); } class Myapp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('小栗子'), ), body: HomePage(), )); } } //自定义有状态组件 class HomePage extends StatefulWidget { HomePage({Key? key}) : super(key: key); @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int countnum = 0; @override Widget build(BuildContext context) { return Container( child: Column( children: <Widget>[ SizedBox(height: 100), Chip(label: Text("${this.countnum}")), SizedBox(height: 10), ElevatedButton( child: Text('按钮'), onPressed: () { setState(() { //只有有状态组件才有 this.countnum++; }); }, ) ], ), ); } } 自定义底部导航条 实现页面切换 模块化BottomNavigationBar组件 是底部导航条,可以让我们定义底部Tab切换,bottomNavigationBar是SCaffold组件的参数。
属性:items 底部导航栏按钮集合类型为List
iconSize:icon
currentIndex:默认选中第几个,
onTap:选中变化回调函数,触发的方法
fixedColor:选中的颜色
type BottomNavigationBarType.fixed//底部可以有多个按钮
导航条,页面切换
import 'package:flutter/material.dart'; import 'tabs/home.dart'; import 'tabs/home2.dart'; //自定义有状态组件 class Tabs extends StatefulWidget { Tabs({Key? key}) : super(key: key); @override _TabsState createState() => _TabsState(); } class _TabsState extends State<Tabs> { List _pageList = [ HomePage(), Home2Page(), ]; int _curentindex = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('小栗子'), ), body: Text(this._pageList[this._curentindex]), bottomNavigationBar: BottomNavigationBar( currentIndex: this._curentindex, onTap: (int index) { //底部菜单点击出发的方法 setState(() { this._curentindex = index; //实现点击选中的功能 }); }, items: [ BottomNavigationBarItem( icon: Image.network(""), label: "首页", ), BottomNavigationBarItem( icon: Image.network(""), label: "优惠券", ), BottomNavigationBarItem( icon: Image.network(""), label: "用户管理", ), BottomNavigationBarItem( icon: Image.network(""), label: "我的", ), ], ), ); } } 路由、基本路由、基本路由跳转传值路由就是页面跳转,在Flutter中通过Navigator组件管理路由导航,提供了管理堆栈的方法,
Navigator.push和Navigator.pop
flutter有两种配置路由跳转的方式1.基本路由 2命名路由
首页跳转到搜索页面
1.需要在首页HomePage中引入SearchPage.dart,2.使用Navigator.pop方法
Navigator.of(context)//路由跳转 .push(MaterialPageRoute(builder: (context) => searchPage()));2.floatingActionButton:浮动按钮
命名路由,命名路由的传值(官方文档)在MaterialApp配置路由,直接通过navigator跳转
路由替换(Navigator.of(context).pushReplacementNamed()),返回到根路由普通路由跳转到根目录:pushAndRemoveUntil()
自定义顶部导航按钮图标颜色以及tabbar定义顶部Tab切换debugShowCheckedModeBanner:false; //去掉debug图标 在main.dart里面
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main(){ runApp(MyApp()); // runApp(new Center(//实例化组件 // child:new Text(//再dart里面,实例化类时new可以省略。 // '你好Flutter', // textDirection: TextDirection.ltr, // ) // )); } //自定义组件 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return HomeContent(); // return MaterialApp( // home:Scaffold( // appBar: AppBar( // title: Text('flutter demo'), // ), // body: HomeContent(), // ) // ); } } class HomeContent extends StatelessWidget{ @override Widget build(BuildContext context) { // TODO: implement build return Center(//实例化组件 child:new Text(//再dart里面,实例化类时new可以省略。 '你好Flutter11', style: TextStyle( fontSize: 40.0, color:Colors.yellow ), textDirection: TextDirection.ltr, ) ); } } // Copyright 2018 The Flutter team. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:math'; import 'package:english_words/english_words.dart'; import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //final wordPair=WordPair.random(); return MaterialApp( title: 'Startup Name Generator', theme:new ThemeData( primaryColor: Colors.pink.shade200, ), home: RandomWords(), // appBar: AppBar( // title: const Text('Welcome to Flutter'), // ), // // body: const Center( // // child: Text('Hello World'), // body:Center( // //child:Text(wordPair.asPascalCase), // child: RandomWords(), // ), ); } } class RandomWords extends StatefulWidget { // const RandomWords({Key? key}) : super(key: key); @override _RandomWordsState createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { final List<WordPair> _suggestions=<WordPair>[]; final Set<WordPair> _saved=new Set<WordPair>();//存储用户喜欢的单词对 //final _suggestions=<WordPair>[];//保存建议的单词对 final TextStyle _biggerFont=const TextStyle(fontSize:18.0);//增大字体大小 // ignore: non_constant_identifier_names Widget_buildSuggestions(){ return ListView.builder( padding: const EdgeInsets.all(16.0), itemBuilder:(context,i){ if(i.isOdd) return const Divider(); final index=i~/2; if(index>=_suggestions.length){ _suggestions.addAll(generateWordPairs().take(10)); } return _buildRow(_suggestions[index]); }); } // ignore: camel_case_types Widget _buildRow (WordPair pair){ final bool alreadySaved=_saved.contains(pair);//确保单词还没有被加入收藏夹 return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), trailing: new Icon( alreadySaved?Icons.favorite:Icons.favorite_border, color: alreadySaved?Colors.red:null, ), onTap: (){ setState(() { if(alreadySaved){ _saved.remove(pair); }else{ _saved.add(pair); } }); }, ); } @override Widget build(BuildContext context) { // final wordPair=WordPair.random(); // return Text(wordPair.asPascalCase); return Scaffold( appBar: AppBar( title:const Text('Startup Name Generator'), actions:<Widget>[ new IconButton(icon:const Icon(Icons.list),onPressed:_pushSaved), ], ), body:Widget_buildSuggestions(), ); //return Container(); } void _pushSaved(){ Navigator.of(context).push( new MaterialPageRoute<void>( builder:(BuildContext context){ final Iterable<ListTile> tiles=_saved.map( (WordPair pair){ return new ListTile( title:new Text( pair.asPascalCase, style: _biggerFont, ), ); }, ); final List<Widget> divided=ListTile.divideTiles( context:context, tiles:tiles, ).toList(); return new Scaffold( appBar:new AppBar( title:const Text('Saved Suggestions'), ), body:new ListView(children:divided), ); }, ), ); } }[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BVv6UG1v-1640866944958)(D:\前端学习\Dart学习\flutt-app1.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fdmVedxX-1640866944960)(D:\前端学习\Dart学习\flutter-app2.png)]
Flutter container组件、Text组件
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。 |
标签: #Flutter笔记 #flutter中文网