irpas技术客

flutter一些学习笔记_甜甜小栗子吖_flutter笔记

irpas 1181

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两个组装饰App

MaterialApp封装了应用程序实现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中文网