Flutter:计数器应用分析

前言

在上一篇文章 Flutter:环境搭建、项目创建 中我们搭建好了环境,并使用命令flutter create 项目名称 创建了一个默认应用。下面来简单看一下该默认应用。

参考:

Flutter案例分析

计数器应用示例

目录结构

切换到项目下可以看到如下图:
在这里插入图片描述

  • .dart_tool 存放与项目相关的一些工具包信息,不要随便修改
  • .ideaAndroid Studio 是基于 IDEA 开发的,所以会有一个.idea,是对当前项目的一些基本配置
  • androidios 对应安卓和苹果两个工程
  • lib 后续我们进行flutter开发,所有代码都放在该目录下。该目录下会有一个main.dart ,该文件作为整个flutter 项目的一个启动入口
  • test 用于做测试
  • linuxmacoswebwindow 对应其他平台,毕竟Flutter 的目标是跨平台(目前好像还不太成熟,当前主要用于app开发)
  • .gitignore 这个就不说了,搞过开发的都知道是干嘛的
  • .metadata 用来记录与版本有关的一些信息,不要修改
  • .packagespubspec.lockpubspec.yaml 与使用第三方库有关
  • README.md 这个也不过多介绍了

实际开发中主要会用到 libpubspec.yaml

按钮

第一次启动项目
在这里插入图片描述
热更新和热重启
在这里插入图片描述
在这里插入图片描述
热更新主要更新build 方法里面的内容,热重启会重新启动项目。

main.dart

导入包

import 'package:flutter/material.dart';

此行代码作用是导入了 Material UI 组件库。Material (opens new window)是一种标准的移动端和web端的视觉设计语言, Flutter 默认提供了一套丰富的 Material 风格的UI组件。

应用入口

void main() {
    
    
  runApp(const MyApp());
}

runApp 函数,存在于 Material UI 组件库
从下图中可以看到runApp函数需要一个Widget 类型的参数
在这里插入图片描述
在这里Widget是一个抽象类,所以需要实例化它的子类 class MyApp extends StatelessWidget {}

简单示例

非常推荐 看一下 Flutter案例分析这个教学视频,里面的老师说的很正确,不要死记硬背,可以通过查看源码的方式来知道需要哪些参数。(window是ctrl+鼠标可以查看对应类的源码)

void main() {
    
    
  runApp(const Text("Hello Flutter",
      textDirection: TextDirection.ltr, textAlign: TextAlign.center));
}

查看Text 类,可以知道需要一个必填参数,也就是文本。这里还需要一个可选参数textDirection :文字排列方向。点开textDirection 可以看到 textDirection 需要一个枚举值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

void main() {
    
    
  runApp(const Center(
    child: Text("Hello Flutter", textDirection: TextDirection.ltr,style:TextStyle(
      color:Colors.blue,
      fontSize:30
    ) ,),
  ));
}

垂直并且水平居中

使用Material UI 的示例

void main() {
    
    
  runApp(MaterialApp(
      home: Scaffold(
    // Scaffold是内置的脚手架,帮助我们快速的搭建页面
    appBar: AppBar(
      title: const Text("第一个 Flutter App"),
    ), //app顶部导航栏
    body: const Center(
      child: Text("Hello Flutter",
          style: TextStyle(color: Colors.blue, fontSize: 30)),
    ),
  )));
}

在flutter可以理解为万物皆是Widget,可以通过嵌套Widget来实现一些功能。一层层嵌套搞得有点晕,而且有些类的实例还要求用const 进行定义

效果图
在这里插入图片描述

嵌套问题的解决

为了解决嵌套问题,可以将代码抽离成一个个的Widget。
Widget分为有状态和无状态两种:

  • 有状态:StatefulWidget,在允许过程中需要改变一些数据时使用
  • 无状态:StatelessWidget,内容是确定的,没用数据的改变时使用

注: 所有的widget里都不能写状态

runApp 方法的参数就是一个Widget,可以将这一部分进行抽离

void main() {
    
    
  runApp( const MyApp());
}

//抽离runApp的参数为一个widget

class MyApp extends StatelessWidget{
    
    
  const MyApp({
    
    Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    // build告诉flutter我们的widget希望渲染什么
    //build方法没办法主动执行,只有数据发生改变时才会执行

    //返回一个Widget
    return MaterialApp(
        home: Scaffold(
          // Scaffold是内置的脚手架,帮助我们快速的搭建页面
          appBar: AppBar(
            title: const Text("第一个 Flutter App"),
          ), //app顶部导航栏
          body: const Center(
            child: Text("Hello Flutter",
                style: TextStyle(color: Colors.blue, fontSize: 30)),
          ),
        ))
  }
}

此时main方法里只有一条语句,这时可以使用箭头函数简写

main() =>  runApp( const MyApp());

YCHomePage 进行进一步抽取,最终代码

import 'package:flutter/material.dart';

//使用箭头函数简写
main() => runApp(const MyApp());

//抽离runApp的参数为一个widget
class MyApp extends StatelessWidget {
    
    
  const MyApp({
    
    Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    // build告诉flutter我们的widget希望渲染什么
    //build方法没办法主动执行,只有数据发生改变时才会执行

    //返回一个Widget
    return const MaterialApp(home: YCHomePage());
  }
}

//首页
class YCHomePage extends StatelessWidget {
    
    
  const YCHomePage({
    
    Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
        // Scaffold是内置的脚手架,帮助我们快速的搭建页面
        appBar: AppBar(
          title: const Text("第一个 Flutter App"),
        ), //app顶部导航栏
        body: const YCContentBody());
  }
}

//内容
class YCContentBody extends StatelessWidget {
    
    
  const YCContentBody({
    
    Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    return const Center(
      child: Text("加油!", style: TextStyle(color: Colors.blue, fontSize: 30)),
    );
  }
}

demo

视频讲解见:Flutter 案例分析

在Flutter开发中,所有的widget都不能定义状态,因为widget是不变的。
在这里插入图片描述
但是StatelessWidget中有一个抽象方法createState,通过实现该抽象方法来定义一个单独的类用来管理状态
在这里插入图片描述

import 'package:flutter/material.dart';

//使用箭头函数简写
main() => runApp(const MyApp());

//抽离runApp的参数为一个widget
class MyApp extends StatelessWidget {
    
    
  const MyApp({
    
    Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    // build告诉flutter我们的widget希望渲染什么
    //build方法没办法主动执行,只有数据发生改变时才会执行

    //返回一个Widget
    return const MaterialApp(home: YCHomePage());
  }
}

//首页
class YCHomePage extends StatelessWidget {
    
    
  const YCHomePage({
    
    Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
        // Scaffold是内置的脚手架,帮助我们快速的搭建页面
        appBar: AppBar(
          title: const Text("第一个 Flutter App"),
        ), //app顶部导航栏
        body: const YCContentBody());
  }
}

//内容
class YCContentBody extends StatefulWidget {
    
    
  const YCContentBody({
    
    Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    
    
    //单独定义一个类,用来管理状态
    return YCContentState();
  }
}

//状态维护类,点开State可以看到其对应的泛型是StatefulWidget,而YCContentBody继承自StatefulWidget
class YCContentState extends State<YCContentBody> {
    
    
  var flag = true;
  @override
  Widget build(BuildContext context) {
    
    
    return Center(
        child: Row(
            //设置x轴的对齐方式
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
          Checkbox(
            value: flag,
            onChanged: (value) {
    
    
              //不能直接赋值,需要借助setState方法,setState方法是继承自State的,用来改变状态
              setState(() {
    
    
                flag = value ?? false; //判定value是否为null
              });
            },
          ),
          const Text(
            "同意协议",
            style: TextStyle(fontSize: 20),
          )
        ]));
  }
}

在这里插入图片描述

哎,感觉对我这种初学者有亿点点难。

猜你喜欢

转载自blog.csdn.net/weixin_41897680/article/details/125901725