Flutter - 初体验

news/2025/2/22 23:58:41

项目文件目录结构介绍

注:创建 Flutter 项目名称不要包含特殊字符,不要使用驼峰标识

// TODO

开发中运行一个 Flutter 三种启动方式

Run 冷启动从零开始启动
Hot Reload 热重载执行 build 方法
Hot Restart 热重启重新运行整个 APP

先看效果,最终要实现一个复选框点击效果

代码会从简到繁一点一点增加

代码分析

// Dart 程序入口是 main 函数,Flutter 是 Dart 编写的,所以入口也是 main 函数
main(){
  /**
   * 1. runApp 函数 (Flutter 内部提供的一个函数)
   * 当启动一个 Flutter 应用程序时调用 runApp
   */
  runApp(
    /**
     * runApp入参:Widget
     *
     * 2 Widget(Flutter 中万物皆 Widget)
     * 整个应用程序中所看到的内容几乎都是 Widget,甚至是内边距的设置,
     * 需要使用一个叫 Padding 的 Widget 来做
     */
  );
}

改进页面样式

main() {
  runApp(
      /**
     * 需求:
     * 1 居中显示: 需要使用另外一个Widget,Center
     * 2 文字大一些: 需要给Text文本设置一些样式
     * 在 Text 小部件外层包装了一个 Center 部件,让 Text 作为其 child
     */
      Center(
          child: Text('Hello Flutter',
              textDirection: TextDirection.ltr,
              style: TextStyle(
                  fontSize: 28,
                  color: Colors.red
              )
          )
      )
  );
}

改进页面结构

main() {
  runApp(
      /**
       * 需求:添加导航栏
       * 最外层包裹一个 MaterialApp【Material 是 Google 推行的一套设计风格、设计规范】
       * title:Android 系统中打开多任务切换窗口时显示的标题;(可以不写)
       * home:应用启动时显示的页面,传入了一个 Scaffold
       *
       * Scaffold:
       * 直译:[脚手架],作用:搭建页面的基本结构
       * 所以给 MaterialApp 的 home 属性传入了一个 Scaffold 对象,作为启动显示的 Widget
       * Scaffold 也有一些属性,如 appBar 和 body
       * appBar:用于设计导航栏,传入了一个 title 属性
       * body:页面的内容,传入了之前已经创建好的 Center 中包裹的一个 Text 的 Widget
       */
      MaterialApp(
        home: Scaffold(
            appBar: AppBar(
              title: Text('Title'),
            ),
            body: Center(
            child: Text('Hello Flutter',
                textDirection: TextDirection.ltr,
                style: TextStyle(fontSize: 28, color: Colors.red))
            )
        ),
      )
  );
}

功能进阶

main() {
  runApp(
      /**
       * 需求:改为一个复选框,复选框右边有说明文案
       * Row: 一个水平布局的小部件,将子控件水平排列
       */
      MaterialApp(
        home: Scaffold(
            appBar: AppBar(
              title: Text('这是Flutter Title'),
            ),
            body: Center(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Checkbox(
                      value: true,
                      onChanged: (value) => print('Checkbox 被点击了')
                  ),
                  Text(
                      '同意条款',
                      style: TextStyle(fontSize: 22),
                  )
                ],
              )
            )
        ),
      )
  );
}

代码到此层级嵌套已很多,且Checkbox点击有问题,此处会引出 StatefulWidget / StatelessWidget

代码重构

main() {
  runApp(
      /**
     * Flutter 开发过程中会形成一个 Widget树,层级嵌套属正常
     * Flutter 代码缩进,开发中使用 2个空格
     *
     * 问题:开发这么简单的程序出现这么多层级嵌套,后期应用程序更复杂层级嵌套会非常恐怖
     * 解决:可以对代码进行封装,将它们封装到自定义 Widget 中,创建自己的 Widget
     *
     * 在 Flutter开发中,可以继承 StatelessWidget/StatefulWidget 自定义 Widget 类
     * 有状态的Widget: StatefulWidget 在运行过程中有一些状态需要改变程序
     * 无状态的Widget: StatelessWidget 内容是确定没有状态的改变,无状态Widget通常仅仅做一些展示
     *
     * 先使用 StatelessWidget 重构:
     * StatelessWidget 通常是一些没有状态(State,也可以理解成data)需要维护的 Widget
     * 它们的数据通常是直接写死(放在Widget中的数据,必须被定义为 final)
     * 从 parent widget中传入的且一旦传入就不可修改
     */
      MyApp());
}

/**
 * StatelessWidget 包含一个必须重写的方法:build()
 * Flutter 在拿到自定义的 StatelessWidget 时,会执行它的 build 方法
 * StatelessWidget 没办法主动去执行 build方法,当使用的数据发生改变时,build方法会被重新执行
 *
 * build 方法执行:
 * 1 当 StatelessWidget 第一次被插入到Widget树中时(第一次被创建时)
 * 2 当父 Widget(parent widget)发生改变时,子 Widget会被重新构建
 * 3 如果自定义的 Widget 依赖 InheritedWidget 的一些数据,InheritedWidget数据发生改变时
 */
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: MyHomePage()
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('这是Flutter Title'),
        ),
        body: MyCenterBody());
  }
}

// flag:状态
// Stateful不能定义状态 -> 创建一个单独的类,这个类负责维护状态
// Widget 不加下划线_ ,因为需要暴漏给别人使用
class MyCenterBody extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyContentBodyState();
  }
}

// State加下划线_ ,因为状态只给 Widget 使用
class _MyContentBodyState extends State<MyCenterBody>{
  var flag = true;
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Checkbox(
                value: flag,
                onChanged: (value){
                  setState(() {
                    flag = value!;
                  });
                }
            ),
            Text(
              '同意条款',
              style: TextStyle(fontSize: 20),
            )
          ],
        )
    );
  }
}

ListView项目

 

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomeContent()
    );
  }
}

class MyHomePage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar:AppBar(
          title: Text('图片列表')
      ) ,
      body: MyHomeContent(),
    );
  }
}

class MyHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        MyItem(
            'kotlin',
            'Kotlin 是一门现代但已成熟的编程语言,旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作,并提供了多种方式在多个平台间复用代码,以实现高效编程。',
            'https://img1.baidu.com/it/u=3448265981,2295756675&fm=253&fmt=auto&app=138&f=JPEG?w=682&h=343'
        ),
        SizedBox(height: 8,),
        MyItem(
            'dart',
            'Dart 是一种基于类的可选类型化编程语言,设计用于创建 Web 应用程序。 Google 称,Dart 的设计目标是为 Web 编程创造结构化但又富有灵活性的语言;',
            'https://img0.baidu.com/it/u=546698500,87821893&fm=253&fmt=auto&app=138&f=PNG?w=1008&h=500'
        ),
        SizedBox(height: 8,),
        MyItem(
            'swift',
            'Swift是苹果公司于2014年WWDC苹果开发者大会发布的新开发语言,可与Objective-C共同运行于macOS和iOS平台,用于搭建基于苹果平台的应用程序。',
            'https://img1.baidu.com/it/u=4069946616,401541856&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=374'
        ),
      ],
    );
  }
}

class MyItem extends StatelessWidget{

  final String title;
  final String info;
  final String imgUrl;

  // 如果直接写在 Text 内部,每次刷新都会调用,直接提出来
  final styleTitle = TextStyle(fontSize: 20,color: Colors.blue,decoration: TextDecoration.none);
  final styleInfo = TextStyle(fontSize: 12,color: Colors.red,decoration: TextDecoration.none);

  MyItem(this.title,this.info,this.imgUrl);

  @override
  Widget build(BuildContext context) {
    return Container(
      // 设置内边距
      padding: EdgeInsets.all(12),
      decoration: BoxDecoration(
        border: Border.all(
          width: 2, // 设置边框宽度
          color: Colors.blue // 设置边框颜色
        )
      ),
      child: Column(
        // 子 widget 对齐方式
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(title,style: styleTitle),
          Text(info,style: styleInfo),
          // 设置间距
          SizedBox(height: 8.0),
          Image.network(imgUrl)
        ],
      ),
    );
  }
}


http://www.niftyadmin.cn/n/5862857.html

相关文章

ubuntu磁盘清理垃圾文件

大头文件排查 #先查看是否是内存满了&#xff0c;USER 很高即是满了 du -f#抓大头思想&#xff0c;优先删除大文件#查看文件目录 内存占用量并排序&#xff0c;不断文件递归下去 du --max-depth1 -h /home/ -h | sort du --max-depth1 -h /home/big/ -h | sort 缓存文件清理…

纳米科技新突破:AbMole助力探索主动脉夹层的基因密码

近日&#xff0c;一项来自青岛大学附属医院转化医学研究所的研究&#xff0c;为我们揭示了利用AbMole产品助力探索主动脉夹层基因治疗的新路径。 研究背景&#xff1a;主动脉夹层的迷雾与挑战 主动脉夹层&#xff0c;作为一种危及生命的疾病&#xff0c;其发病率和死亡率均居…

Spring Boot框架总结(超级详细)

前言 本篇文章包含Springboot配置文件解释、热部署、自动装配原理源码级剖析、内嵌tomcat源码级剖析、缓存深入、多环境部署等等&#xff0c;如果能耐心看完&#xff0c;想必会有不少收获。 一、Spring Boot基础应用 Spring Boot特征 概念&#xff1a; 约定优于配置&#…

ue5.2.1 quixel brideg显示asset not available in uAsset format

我从未见过如此傻x的bug&#xff0c;在ue5.2.1上通过内置quixel下载资源显示 asset not available in uAsset format 解决办法&#xff1a;将ue更新到最新版本&#xff0c;通过fab进入商场选择资源后add to my library 点击view in launcher打开epic launcher&#xff0c;就可…

【vue项目如何利用event-stream实现文字流式输出效果】

引言 在现代 Web 应用中&#xff0c;实时数据展示是一个常见需求&#xff0c;例如聊天消息逐字显示、日志实时推送、股票行情更新等。传统的轮询或一次性数据加载方式无法满足这类场景的流畅体验&#xff0c;而 流式传输&#xff08;Streaming&#xff09; 技术则能实现数据的…

Docker安装Open WebUI教程

Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 AI 平台,旨在完全离线运行。它支持各种LLM运行器,如 Ollama 和 OpenAI 兼容的 API,并内置了 RAG 推理引擎,使其成为强大的 AI 部署解决方案。 官网文档地址:https://docs.openwebui.com/ 一、拉取镜像 下载的镜像包比…

8. Flink-CDC

1. Flink-CDC的介绍 Flink-cdc主要是用来同步数据库中的数据&#xff0c;它的主要优势在于基于Flink框架直接用Flink Stream Api 或Flink SQL 直接编程&#xff0c;不需要引入第三方组件 2.Flink-CDC的使用 Flink-cdc在使用上需要注意的点 注意Flink-cdc在2.1版本之前需要导…

跟着李沐老师学习深度学习(十三)

现代循环神经网络 循环神经网络中梯度异常在实践中的意义引发了一些问题&#xff1a; 早期观测值影响重大&#xff1a;早期观测值对预测所有未来观测值极为重要&#xff0c;如序列中第一个观测值包含校验和&#xff0c;需在序列末尾辨别其是否正确&#xff0c;若无特殊机制存…