快速开始Flutter

作者: 浅墨入画 | 来源:发表于2021-11-19 23:55 被阅读0次

    创建Flutter工程

    flutter工程名文件夹文件命名规则: 不要用驼峰不要用大写不要用中文
    类名可以用驼峰命名

    创建工程方式
    • 命令创建
    // -i objc指定 OC语言,hello_flutter为工程名
    flutter create -i objc hello_flutter
    
    • 工具栏创建
    image.png
    • Android Studio启动页创建入口
    image.png
    配置Flutter SDK路径
    image.png
    Flutter工程配置
    • 配置androidios语言类型,选择平台类型
    image.png
    • 选择工程Project
    image.png
    • 选择模拟器,运行flutter工程
    image.png 成功运行
    Flutter能运行在iOS与Android平台的原因是什么?

    原因是在iOS与Android平台都安装了渲染引擎

    Flutter与RN的本质区别?
    • RN:对原生UIUIKit的包装,一旦原生UI产生更新,那么RN也需要进行更新,对原生的依赖性很强,RN有热更新
    • Flutter:把不同平台的渲染引擎安装在手机上,渲染引擎负责解析Dart代码进行页面展示,Flutter有热重载
      优点:效率高,不依赖于UI,安卓iOS高度统一
      缺点:引入渲染引擎会导致安装包体积增大

    hello_flutter

    更新Flutter版本
    // 检查flutter环境配置
    $ flutter doctor
    // 更新flutter版本
    $ flutter upgrade
    
    解决Android Studio快捷键Cmd + Q的bug

    Android Studio如果使用快捷键Cmd + Q强退,有可能会锁住当前的运行环境。一旦锁住运行环境,再次打开工程就有可能出现问题,原因是Android Studio中为了保护数据,里面有一个缓存机制

    解决方案
    强退Android Studio导致flutter卡住了,就需要删除缓存文件,lockfile文件目录~/flutter/bin/cache/lockfile

    删除flutter SDK目录下的lockfile文件
    开始Flutter编写
    • 实现基层组件都需要导入头文件material.dart导入常用的素材类似于iOS中的UIKit
    // 导入flutter的UI库,类似于iOS的UIKit
    import 'package:flutter/material.dart';
    
    • 在 iOS中运行APP 是在window中,在Flutter中使用runApp,在这个里面添加组件,我们先来看看Text组件
    // flutter入口函数
    void main() {
      runApp(const Center(
        child: Text(
          'helloFlutter',
          textDirection: TextDirection.ltr,
        ),
      ));
    }
    
    1. 当前运行页面里面有两个小部件CenterText,都是继承于Widget
    2. Center相当于OC中的viewchild相当于subView的意思
    3. Text相当于UILabel
    运行效果

    flutter是增量渲染,不会改变组件内容,会直接用新的组件替换旧的组件,直接修改控件本身,以此改变值,所以效率很高;flutter没有页面层级它只有一层页面

    Dart中的var、final 和 const介绍
    • var声明变量
    void main() {
      var a;//变量
      print(a); // 打印结果为null
    
      var b;//变量
      b = "this is b !";
      print(b); // 打印结果为 this is b !
    }
    
    1. var声明的变量,没有指定值,也没有指定类型,是一个动态类型,鼠标放上去会提示类型!
    2. dart中使用var声明变量,可以赋值不同类型的值,会自动推断变量的类型和Swift中是一样的效果。
    3. var声明的变量如果没有初始化,那么它的值是null
    • final声明变量
    void main(){
      final a = 10;
      a = "hello"; // 运行报错
    
      final b;
      b = "hello";
      print(b); // 打印结果为 hello
    
      final c;
      print(c); // 运行报错
    }
    
    1. final修饰的是一个最终的变量,不能再次赋值,否则会报错。也可以先声明再次赋值,但是只能赋值一次。
    2. final适用声明以后不会改变的变量,也就类似一个常量的意思,它只能赋值一次。
    3. final声明的变量,不赋值是不可以使用的
    • const声明常量
    void main(){
      const a;
      a = 8; // 运行报错
      
      const b = 8;
      print(b); // 打印结果为 8
    }
    
    1. const修饰常量,声明的时候就得赋值,这也是和变量最大的区别!
    2. const常量也是不可以修改的,不可以再次赋值,这点和 final 一样

    自定义Widget

    Widget分为两大类有状态stateful无状态stateless,其实flutter小组件本质上都是无状态的,有状态只是定义了一些功能方便开发

    • 无状态stateless表示不可变,如果要想改变,用新的组件替换当前组件
    • 有状态stateful表示在当前树中,内部小组件可以更改状态。影响页面渲染的数据保存起来就是有状态的
    自定义Widget
    • 继承于无状态小部件
    • 要想让小部件显示在页面上,必须实现build方法返回Widget
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyWidget());
    }
    // 如果main()里面只有一行代码,可以使用箭头函数进行缩写
    //void main() => runApp(MyWidget());
    
    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: Text(
            'helloFlutter',
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 14,color: Colors.orange,backgroundColor: Colors.white),
          ),
        );
      }
    }
    
    image.png
    flutter热重载

    如果iOS项目过大,编译时间会很长,虽然我们只改了一行代码,想要查看效果,也需要编译很长时间。而flutter开发中有一个好处,不需要重新启动flutter工程。比如我们改了Text文字大小,flutter会增量渲染我们修改的内容,不会重复渲染其他内容,即flutter热重载增量渲染就是用新的小部件直接替换旧的小部件,将内容展示出来。

    如果flutter项目是有状态的,那么数据发生了更改,就需要重新启动flutter项目。即渲染树发生了变化需要重新启动flutter项目

    如果是有状态的小部件,而且状态发生了变化,热重载状态是不会清零的。如果要想把状态清零,需要重新启动项目

    文字样式

    flutter中创建模型对象是不会渲染的。这样的对象成员属性是可以更改的,一旦模型对象的属性发生变化,通过这个模型对象取到新的数据,用来创建新的小部件

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyWidget());
    
    // 继承于无状态小部件
    // 要想让小部件显示在页面上,必须实现build方法,返回Widget
    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: Text(
            'helloFlutter123123',
            textDirection: TextDirection.rtl,
            style: TextStyle(
                fontSize: 40,
                fontWeight: FontWeight.bold,
                color: Colors.orange,
            )
          ),
        );
      }
    }
    
    image.png
    Text组件
    • 创建Text
      Text()构造方法创建
    • Text属性
    textDirection 文本对齐  (必须要写的属性,否则内容不显示)
    TextAlign.center 将文本对齐容器的中心。
    TextAlign.end 对齐容器后缘上的文本。
    TextAlign.justify 拉伸以结束的文本行以填充容器的宽度。即使用了decorationStyle才起效
    TextAlign.left 对齐容器左边缘的文本。
    TextAlign.right 对齐容器右边缘的文本。
    TextAlign.start 对齐容器前缘上的文本。
    maxLines 最大行数
    overflow 处理字数溢出
    TextOverflow.clip 剪切溢出的文本以修复其容器。
    TextOverflow.ellipsis 使用省略号表示文本已溢出。
    TextOverflow.fade 将溢出的文本淡化为透明。
    textScaleFactor 字号系数
    
    • TextStyle style属性
    color 文本颜色。
    decoration 绘制文本装饰:
    下划线(TextDecoration.underline)
    上划线(TextDecoration.overline)
    删除线(TextDecoration.lineThrough)
    无(TextDecoration.none)
    
    decorationStyle 绘制文本装饰的样式:
    画一条虚线 TextDecorationStyle.dashed
    画一条虚线 TextDecorationStyle.dotted
    画两条线 TextDecorationStyle.double
    画一条实线 TextDecorationStyle.solid
    画一条正弦线(波浪线) TextDecorationStyle.wavy
    
    fontWeight 绘制文本时使用的字体粗细:
    FontWeight.bold 常用的字体重量比正常重。即w700
    FontWeight.normal 默认字体粗细。即w400
    FontWeight.w100 薄,最薄
    FontWeight.w200 特轻
    FontWeight.w300 轻
    
    fontStyle 字体变体:
    FontStyle.italic 使用斜体
    FontStyle.normal 使用直立
    
    textBaseline 对齐文本的水平线:
    TextBaseline.alphabetic:文本基线是标准的字母基线
    TextBaseline.ideographic:文字基线是表意字基线;
    
    fontSize 字体大小
    
    letterSpacing 水平字母之间的空间间隔(逻辑像素为单位)。可以使用负值来让字母更接近。
    wordSpacing 单词之间添加的空间间隔(逻辑像素为单位)。可以使用负值来使单词更接近。
    height 文本行与行的高度,作为字体大小的倍数
    locale 用于选择区域特定字形的语言环境
    background 文本背景色
    foreground 文本的前景色
    shadows 实现一些特殊效果
    

    MaterialApp

    • 素材App
    • home属性,主页面
    • debugShowCheckedModeBanner属性,便于我们在调试版本中做操作
    import 'package:flutter/material.dart';
    
    void main() => runApp(App());
    
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MyWidget(),
        );
      }
    }
    
    // 继承于无状态小部件
    // 要想让小部件显示在页面上,必须实现build方法,返回Widget
    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: Text(
            'helloFlutter123123',
            textDirection: TextDirection.rtl,
            style: TextStyle(
                fontSize: 40,
                fontWeight: FontWeight.bold,
                color: Colors.orange,
            )
          ),
        );
      }
    }
    
    运行效果
    Scaffold小部件
    • ScaffoldMaterial Design布局结构的基本实现,此类提供了用于显示drawersnackbar底部sheet的API,是带有导航栏的小部件。
    • body属性,显示在导航栏下面的区域,需要传递一个Widget
    import 'package:flutter/material.dart';
    
    void main() => runApp(App());
    
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: const Text('FlutterDemo'),
            ),
          ),
        );
      }
    }
    
    // Scaffold主要属性
    appBar:显示在界面顶部的一个 AppBar
    body:当前界面所显示的主要内容
    floatingActionButton: 在 Material 中定义的一个功能按钮。
    persistentFooterButtons:固定在下方显示的按钮。
    drawer:侧边栏控件
    bottomNavigationBar:显示在底部的导航栏按钮栏。
    backgroundColor:背景颜色
    resizeToAvoidBottomPadding: 控制界面内容 body
    是否重新布局来避免底部被覆盖了,比如当键盘显示的时候,重新布局避免被键盘盖住内容。默认值为 true。
    
    image.png

    自定义小部件MyWidget嵌入home

    import 'package:flutter/material.dart';
    
    void main() => runApp(App());
    
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: const Text('FlutterDemo'),
            ),
            body: MyWidget(),
          ),
        );
      }
    }
    
    // 继承于无状态小部件
    // 要想让小部件显示在页面上,必须实现build方法,返回Widget
    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: Text(
            'helloFlutter123123',
            textDirection: TextDirection.rtl,
            style: TextStyle(
                fontSize: 40,
                fontWeight: FontWeight.bold,
                color: Colors.orange,
            )
          ),
        );
      }
    }
    
    image.png

    这个时候Center是相对于body居中的,Center小部件是相对于父视图居中的。

    初探ListView

    下面实现一个类似UITableView的页面

    • 新建model目录,里面创建Car.dart模型
    // <!-- Car.dart文件 -->
    class Car {
      // {} 表示可选,可以给Car赋值,也可以不赋值
      const Car({this.name, this.imageUrl});
      final String? name;
      final String? imageUrl;
    }
    
    • main.dart文件中导入Car.dart
    import 'model/Car.dart';
    
    • ListView最终代码
    import 'package:flutter/material.dart';
    import 'model/car.dart';
    
    void main() => runApp(App());
    
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return MaterialApp(
          // 去掉debug标识
          debugShowCheckedModeBanner: false,
          home: Home(),
        );
      }
    }
    
    class Home extends StatelessWidget {
      //_是指文件内部!!!只在main.dart文件内部可以访问
      Widget _itemForRow(BuildContext context, int index) {
        return Container(
            color: Colors.white,
            margin: const EdgeInsets.all(10),
            // 组件的排列有三种,横着 竖着 叠着
            child: Column(
              children: <Widget>[
                // 命名构造函数,图片是异步加载
                Image.network(datas[index].imageUrl!),
                // SizedBox用于设置图片与文字的间隔,也可以用Container设置间隔
                const SizedBox(
                  height: 10,
                ),
                Text(
                  datas[index].name!,
                  style: const TextStyle(
                    fontWeight: FontWeight.w800,
                    fontSize: 18.0,
                    // italic表示斜体
                    fontStyle: FontStyle.italic,
                  ),
                ),
              ],
            ));
      }
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Scaffold(
          backgroundColor: Colors.grey[100],
          appBar: AppBar(
            title: const Text('FlutterDemo'),
          ),
          // listview构造函数
          body: ListView.builder(
            // 获取_itemForRow,上面定义的Widget
            itemBuilder: _itemForRow,
            itemCount: datas.length,
          ),
        );
      }
    }
    
    //引入`Car`模型数据
    final List<Car> datas = [
      const Car(
        name: '保时捷918 Spyder',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/7d8be6ebc4c7c95b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: '兰博基尼Aventador',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/e3bfd824f30afaac?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: '法拉利Enzo',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/a1d64cf5da2d9d99?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: 'Zenvo ST1',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/bf883b46690f93ce?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: '迈凯伦F1',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/5a7b5550a19b8342?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: '萨林S7',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/2e128d18144ad5b8?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: '科尼赛克CCR',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/01ced8f6f95219ec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: '布加迪Chiron',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/7fc8359eb61adac0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: '轩尼诗Venom GT',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/d332bf510d61bbc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      ),
      const Car(
        name: '西贝尔Tuatara',
        imageUrl:
            'https://img.haomeiwen.com/i2990730/3dd9a70b25ae6bc9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      )
    ];
    
    ListView运行效果
    Container小部件

    Container是一个容器类,一个拥有绘制定位调整大小widget,在Flutter中万物皆widgetwidget是小部件的意思。类似于iOS中的UIView

    • Container组成
    1. Container的最里层的是child元素,child元素首先会被padding包着,然后添加额外的constraints限制,最后添加margin
    2. Container自身尺寸的调节分两种情况:
      Container在没有子节点(children)的时候,会试图去变得足够大。除非constraintsunbounded限制,在这种情况下,Container会试图去变得足够小。
      带子节点的Container,会根据子节点尺寸调节自身尺寸,但是Container构造器中如果包含了widthheight以及constraints,则会按照构造器中的参数来进行尺寸的调节。
    • Container属性
    1. keyContainer唯一标识符,用于查找更新。
    2. alignment:控制child的对齐方式,如果container或者container父节点尺寸大于child的尺寸,这个属性设置会起作用,有很多种对齐方式。
    3. paddingdecoration内部的空白区域,如果有child的话,child位于padding内部。padding与margin的不同之处在于,padding是包含在content内,而margin则是外部边界,设置点击事件的话,padding区域会响应,而margin区域不会响应。
    4. color:用来设置container背景色,如果foregroundDecoration设置的话,可能会遮盖color效果。
    import 'package:flutter/material.dart';
    
    void main() => runApp(App());
    
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Container(
          margin: EdgeInsets.all(10),
          color: Colors.red,
          alignment: Alignment(0,0),
          child: Container(
            margin: EdgeInsets.all(10),
            color: Colors.brown,
            width: 250,
            height: 250,
            child: Text(
              'Hello World',
              textDirection: TextDirection.ltr,
              style: TextStyle(fontSize: 26,color: Colors.blue,backgroundColor: Colors.white),
            ),
          ),
        );
      }
    }
    
    运行效果

    Flutter中文网 - 文档学习
    Dart - 文档学习
    Dart包获取地址

    相关文章

      网友评论

        本文标题:快速开始Flutter

        本文链接:https://www.haomeiwen.com/subject/zugqtrtx.html