美文网首页
Flutter学习笔记4--Flutter初识

Flutter学习笔记4--Flutter初识

作者: percivals | 来源:发表于2021-09-03 15:00 被阅读0次

    本文主要介绍Flutter项目的简单界面构建,以及布局

    一.创建新的Flutter工程

    1. 使用终端进行创建
      flutter create 项目名
      
      不支持大写字母,可以加下划线
      创建成功后,可以使用VSCode或者Android studio打开
    2. 工程内容
      lib文件夹:存放编写的代码,main.dart即为启动入口
    3. 项目启动
      打开iOS或者安卓模拟器, 在工具栏找到启动调试,点击进行启动

    二、flutter项目编写

    1. flutter项目的几个特性
      热重载 hot reload 、 热重启 hot restart
      运行一个flutter项目有三种方式: 冷启动:(从0启动)、 热重载 (最主要是执行build方法,其他方法不受影响)、 热重启(重新运行整个项目)
      使用热重载可以快速预览布局变化,但是只有build方法会重置
    2. 简单编写启动内容
      导入头文件(package:flutter/material.dart), 然后调用runApp函数
      import 'package:flutter/material.dart';
      
      main(List<String> args) {
        runApp(Text("Hello world", textDirection: TextDirection.ltr));
      }
      
    3. 具体内容设置
      textDirection 传入文字方向
      style 设置样式,字体颜色等
      Center 也是一个Widget,实现居中操作
      runApp(Center(
        child: Text("Hello world",
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 30, color: Colors.red))));
      

    三、Material设计风格

    1. Widget 即组件
      万物皆是Widget, 通过嵌套Widget来实现布局功能
      • 有状态的Widget:
        StatefulWedget 在运行过程中有一些状态(data数据)需要改变
      • 无状态的Widget:
        StatelessWidget 内容是确定的,没有状态(data数据)的改变
    2. 几种Widget
    • MaterialApp 会自动添加某些默认配置,不需要手动进行设置,比如文字方向等
       runApp(MaterialApp(
        home: Center(
            child: Text("Hello World",
                style: TextStyle(fontSize: 30, color: Colors.orange)))));
      
    • Scaffold 脚手架 用于快速搭建页面 创建导航栏、Tabbar等
      主要参数有 appBar(导航栏或者Tabbar),body(界面内容)
      runApp(MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            appBar: AppBar(
                title: Text(
              "第一个项目",
              style: TextStyle(fontSize: 20, color: Colors.white),
            )),
            body: Center(
                child: Text("Hello world",
                    textDirection: TextDirection.ltr,
                    style: TextStyle(fontSize: 30, color: Colors.red))))));
      
      debugShowCheckedModeBanner 控制右上角debug标签的显示
    1. 自定义Widget子类
      class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            // TODO: implement build
            return Text("hello World");
          }
        }
      

    build方法: 在创建自定义Widget子类时,会执行它的build方法,返回一个希望渲染的Widget元素,例如上例所示的Text Widget

    StatelessWidget没办法去主动执行build方法,当我们的数据发生改变的时候,build方法会被重新执行

    • build方法在什么情况下会执行?
      1)当对应的StatelessWidget第一次被插入到Widget树中时,即第一次创建时
      2) 当对应的父Widget发生改变时,子Widget会被重新构建
      3) 如果对应的Widget依赖inheritedWidget的一些数据,inheritedWidget数据发生改变时

    将需要构造的Widget放到build方法中返回,然后直接调用编写的Widget子类,即可得到想要的界面```

    main(List<String> args) {
            runApp(MyApp());
          }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            debugShowCheckedModeBanner: false,
            home: Scaffold(
                appBar: AppBar(
                    title: Text(
                  "第一个项目",
                  style: TextStyle(fontSize: 20, color: Colors.white),
                )),
                body: Center(
                    child: Text("Hello world",
                        textDirection: TextDirection.ltr,
                        style: TextStyle(fontSize: 30, color: Colors.red)))));
      }
    }
    
    1. 代码拆分抽取
      将各个Widget包装成一个个自定义Widget子类,再进行组合,完成代码的拆分重组
    main(List<String> args) {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(debugShowCheckedModeBanner: false, home: HomePageView());
      }
    }
    
    class HomePageView extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: Text(
              "第一个项目",
              style: TextStyle(fontSize: 20, color: Colors.white),
            )),
            body: ContentBody());
      }
    }
    
    class ContentBody extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Center(
            child: Text("Hello world",
                textDirection: TextDirection.ltr,
                style: TextStyle(fontSize: 30, color: Colors.orange)));
      }
    }
    
    1. 一行写入多个控件
      横向写入多个控件 Row
      竖向写入多个控件 Column
    class ContentBody extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Center(
            child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
          Text("111"),
          Text("Hello world",
              textDirection: TextDirection.ltr,
              style: TextStyle(fontSize: 30, color: Colors.orange))
        ]));
      }
    }
    

    默认从每行的最左端开始布局,使用mainAxisAlignment参数可以改变行内的布局位置

    1. @immutable
    • 使用@immutable 注解标明的类及其子类均为不可变类,其中的属性均不可变,使用final修饰,不可定义状态
      Widget类使用@immutable标记,所有的Widget都不可以直接定义状态
    • StatelessWidget即是不可更改的类,不可定义状态
    • StatefulWidget内部有一个抽象方法createState,此方法返回一个State类
    • 在自定义的State子类中通过重写build方法实现控件
    • StatefulWidget内部不可直接定义状态,但是可以在自定义的State子类中可以定义状态
    class ContentBody extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return ContentBodyState();
      }
    }
    
    class _ContentBodyState extends State<ContentBody> {
      var flag = true;
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Center(
            child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
          Checkbox(
              value: flag,
              onChanged: (value) {
                setState(() {
                  flag = value ?? false;
                });
              }),
          Text("Hello world",
              textDirection: TextDirection.ltr,
              style: TextStyle(fontSize: 30, color: Colors.orange))
        ]));
      }
    }
    

    总结:
    继承自StatefulWidget的类负责实现createState方法,返回一个State类
    State类负责实现Build方法,以及状态的创建,来实现功能

    另外需要注意的几点:

    • 状态的改变需要在setState回调中进行,否则不生效
    • State类一般使用下划线_开头,如_ContentBodyState,下划线开头的类在别的文件无法访问,保证安全,而继承自StatefulWidget的类不加下划线

    问题1:上述示例中,ContentBody返回的State类一定要定义为ContentBody泛型吗?可以改成别的StatefulWidget类吗?

    可以,但没必要。
    语法上无问题,但是,定义成此泛型,才可以使用系统提供的一个widget属性来构建出桥梁,连通对应的StatefulWidget子类,所以一般会这么写

    问题2:继承自StatefulWidget的类,具体的作用?

    1). 生成返回State类
    2). 可以接收父Widget传过来的数据

    相关文章

      网友评论

          本文标题:Flutter学习笔记4--Flutter初识

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