美文网首页
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