【Android-Flutter】我的Flutter开发之旅

news2024/11/23 8:51:46

目录:

  • 0、文档:
  • 1、在Windows上搭建Flutter开发环境
      • (1)[使用中国镜像(❌详细看官方文档)](https://docs.flutter.dev/community/china)
      • (2)[下载最新版Flutter SDK(已包含Dart)](https://docs.flutter.dev/release/archive?tab=windows#windows)
      • (3)运行医生检查命令:`flutter doctor`
      • (4)Android Studio中安装Flutter、Dart插件方便使用
  • 2、新建、运行Flutter项目
  • 3、项目结构+分析示例代码
      • (1)几个常用小知识:
      • (2)代码分析:
  • 4、[必看电子书:《Flutter实战·第二版》](https://book.flutterchina.club/chapter2/first_flutter_app.html#_2-1-1-%E5%88%9B%E5%BB%BAflutter%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF)
  • 5、[必看官方例子❌](https://github.com/flutter/samples)

0、文档:

国外的官网(❌科学上网):https://flutter.dev/
国外的文档:https://docs.flutter.dev/

国内的官网:https://flutter.cn
国内的文档:https://flutter.cn/docs/

其他中文版文档(更适合新手):https://doc.flutterchina.club


1、在Windows上搭建Flutter开发环境

❌表示国内访问不了,需要科学上网。

(1)使用中国镜像(❌详细看官方文档)

将如下环境变量加入到用户环境变量中:

export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

在Windows中操作示例:
在这里插入图片描述

(2)下载最新版Flutter SDK(已包含Dart)

上面提供的官网下载,比如❌https://docs.flutter.dev/release/archive?tab=windows#windows
国外的访问不了,就国内的看看,或者科学上网。

下载完成后,解压到C盘自己新建一个目录管理(不要放在高权限的路径如C:\Program Files\)。

这个SDK其实就是命令,所以我们需要配置环境变量方便重复调用:
在“用户变量”下“Path”:加一个 flutter\bin的全路径作为它的值.
命令名为:flutter
·
第一次运行一个flutter命令(如flutter doctor等)时,它会下载它自己的依赖项并自行编译。以后再运行就会快得多。

(3)运行医生检查命令:flutter doctor

查看是否需要你的电脑是否还需要安装其他任何依赖项来完成安装,然后根据检查结果适当调整

  • 一般Flutter SDK已经包含包括Dart的SDK之类的东西,所以不需要额外安装Dart SDK
  • [!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
    这个警告因为你没同意协议,所以你需要运行一下它提示的这个命令同意一下协议:flutter doctor --android-licenses
    如果这一块还有其他报错就是你的Android Studio的SDK里,你有些东西没勾选下载。
    在这里插入图片描述
  • 还有一个问题是Visual Studio - develop Windows apps,意思就是你不开发电脑PC端应用你就不需要VS,如果需要再自行下载安装。
    我的最终结果示例:
    在这里插入图片描述其他你可能会遇到的问题:

问题2:如上图,Android Studio不能找到JAVA版本(JDK版本)

解决办法:
把JDK里的文件复制到Android Studio安装目录下的jre即可:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

问题3:使用JDK安装程序(exe),会自动配置JDK环境变量。如果是多版本,需要删除系统变量Path下的这个。(否则会错乱)
在这里插入图片描述

其他常用命令:

flutter devices :验证Flutter识别您连接的Android设备。
flutter run:运行启动您的应用程序(项目)到不同的设备,所以运行这个命令之前你需要先创建Flutter项目,并导航到具体的目录下去运行。当然,也可以直接再AS中直接点击运行。

(4)Android Studio中安装Flutter、Dart插件方便使用

在这里插入图片描述
现在安装Flutter就会提示一起安装Dart插件,如果没提示,就自己搜索Dart插件安装。

重启AS,就可以看到可以直接使用AS新建Flutter项目了:
在这里插入图片描述


2、新建、运行Flutter项目

说明:我做这个记录的时候是2023年8月份,所有版本都是刚刚下载的,所以如果你使用老版本,界面可能不一样!

1、在Android Sudio中新建Flutter项目

2、选择flutter,第一次需要配置flutter SDK,路径为bin目录的上一层(也就是flutter目录

如图:
在这里插入图片描述3、自行填写项目信息,最后一句提醒的意思是:
(1)When created, the new project will run on the selected platforms (others can be added later).
创建后,新项目将在选定的平台上运行(其他平台可以稍后添加)。
(2)Create project offline
离线创建项目

4、新建项目后,代码位于 lib/main.dart.

5、运行在浏览器上是很快的,但是在手机上却很慢(构建很久)。
我第一次运行的时候出现一个问题,就是构建很久,似乎构建不出来。
在这里插入图片描述

所以怀疑是gradle工具出错了(可能是之前新建项目,没构建成功,也就是gradle没下载完成,就手动强制退出AS了,导致工具不完整。)
我的解决办法是瞎弄出来的。我就是在插件市场,下载一个Gradle升级的辅助插件,然后自己科学上网,每次重启它会检查然后会自动把Gradle插件升级到最新了。
在这里插入图片描述
在这个过程中发生一个扯淡的问题,就是我可能不小心把其他插件禁用掉了,导致新建项目的选项里没有Flutter项目。
网上说是把这玩意给禁了,重新打开就行了:
在这里插入图片描述


3、项目结构+分析示例代码

(1)几个常用小知识:

1、自动对齐缩进:右键单击Dart代码区域,然后选择 Reformat Code with dartfmt.
2、

(2)代码分析:

1、引入一个库文件:
导入Material:它是一种标准的移动端和web端的视觉设计语言。
Flutter提供了一套丰富的Material widgets。

import 'package:flutter/material.dart';

2、入口函数main:
根据Dart语法,可以改成
void main() => runApp(const MyApp());
说明:main函数使用了(=>)符号, 这是Dart中单行函数或方法的简写

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

3、StatelessWidget无状态和StatefulWidget有状态
StatelessWidget 是一个不可变的组件类,它表示一个静态的用户界面片段。它的特点是一旦被创建,就无法更改其属性或状态。它通常用于显示静态内容,不需要随时间变化的界面。例如,一个简单的文本标签或一个静态图片可以使用 StatelessWidget 来创建。
·
StatefulWidget(有状态组件):StatefulWidget 是一个可变的组件类,它表示一个可以根据内部状态的变化而重新渲染的用户界面片段。它的特点是可以包含可变的状态和属性,并且可以根据状态的变化来动态更新界面。StatefulWidget 通常用于需要响应用户交互、数据变化或时间变化的界面。例如,一个计数器组件可以使用 StatefulWidget 来创建,其中计数器的值可以根据用户的操作进行递增或递减。
·
注意,很多新手会误解,这个“不可变”的地方体现在哪?我们都知道,一个类,一般包含两部分:属性值+方法函数
其中属性值用来描述这个类的属性状态。所以我们说的可变不可变说的是在其中这个类中定义的变量值不可变。
举个例子,一个继承自无状态的类里有一个变量a,这个属性值a不可变的
但是组件是树状的,也就是组件A可能包含组件B,假设组件A是不可变的,组件B是可变的。这是可以的,因为可不可变,是某个组件的属性值,跟其他组件(就算是你包含的组件),没有啥关系。很多新手把握不了这个变化之处,就会觉得很难理解。
·
使用 StatelessWidget 和 StatefulWidget 的分离可以带来一些好处:
(1)渲染性能优化:由于 StatelessWidget 是不可变的,当界面不需要重新渲染时,Flutter 可以避免不必要的重绘操作,从而提高性能。
(2)状态管理:StatefulWidget 允许你在组件内部管理状态,当状态发生变化时,Flutter 会自动触发重新渲染。这使得你可以方便地处理用户交互或数据变化,并及时更新界面。
(3)组件复用:通过将界面的静态部分与动态部分分离,可以更好地实现组件的复用。你可以在 StatelessWidget 中定义静态的界面结构,然后在 StatefulWidget 中处理动态的逻辑和状态。
·
总而言之,StatelessWidget 用于表示静态的界面片段,而 StatefulWidget 则用于表示需要根据状态变化重新渲染的动态界面片段。这种分离使得 Flutter 的界面构建更加灵活、高效和易于维护。

// 1/3 不可变(无状态)
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  // 1、变量属性值区域:此处没有。
  // This widget is the root of your application.
  // 这是一个widget(组件)
  // 这是你应用的根部组件(也就是第一个)
  // 2、函数方法区域:
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        // 这部分是应用的主题。
        //
        // TRY THIS: 
        // Try running your application with "flutter run". You'll see the application has a blue toolbar. 
        // 尝试运行你的应用(使用flutter run命令),就会看到应用上有一个深紫色的导航条
        // Then, without quitting the app,
        // try changing the seedColor in the colorScheme below to Colors.green
        // and then invoke "hot reload" (save your changes or press the "hot reload" button 
        // in a Flutter-supported IDE, or press "r" if you used the command line to start the app).
        // 它的就是想说,它支持热加载,你需要把下面的颜色改成Colors.green绿色,然后点击“热加载”按钮,也就是AS右上角的闪电按钮
        // 或者直接运行,就能够看到修改结果。意思就是不需要重新进行项目编译,这叫热加载。
        // Notice that the counter didn't reset back to zero; the application
        // state is not lost during the reload. To reset the state, use hot restart instead.
        // 注意,你在手机上点几下计数器,热加载以后,计数器并不会清零。也就是说,没有进行修改的部分在热加载过程中不会改变状态。
        // 如果你想改变状态,需要热重启替代。
        // This works for code too, not just values: Most code changes can be tested with just a hot reload.
        // 这也适用于代码,而不仅仅是值:大多数代码更改都可以通过热(重新)加载进行测试。热加载适合代码快速测试。
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),//这是一个有状态的组件,说明在无状态组件里,
      //是可以调用任何组件的,不区分有无状态。有无状态的组件说明的是,这个组件本身的属性,而别的组件的属性就不归它管了。
    );
  }
}
// 2/3  可变(有状态):其实就是需要重写一个方法。并使用这个方法来构建一个具有状态的对象。
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  /*
    This widget is the home page of your application. It is stateful, meaning that
    it has a State object (defined below) that contains fields that affect how it looks.
    这个小部件是应用程序的主页。它是有状态的,也就是说
    它有一个State对象(定义如下),其中包含影响其外观的字段。
  */

  /*
    This class is the configuration for the state. It holds the values (in this case the title)
    provided by the parent (in this case the App widget) and
    used by the build method of the State. Fields in a Widget subclass are always marked "final".
    这个类是状态的配置。它保存值(在本例中为标题)
    由父组件提供(在本例中是App小部件)和
    由该状态的构建方法使用。Widget子类中的字段总是被标记为“final”。
  */

  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}
//  3/3------------------------------------------------
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      /*
      This call to setState tells the Flutter framework that something has
      changed in this State, which causes it to rerun the build method below
      so that the display can reflect the updated values. If we changed
      _counter without calling setState(), then the build method would not be
      called again, and so nothing would appear to happen.
      调用setState来告诉Flutter框架,此状态中有东西发生了变化,
      这导致它重新运行下面的构建方法,以便显示可以反映更新的值。
      如果我们在没有调用setState()的情况下修改了_counter,那么build方法将不会再次被调用,因此什么也不会发生。
      */
      _counter++;
    });
  }

  
  Widget build(BuildContext context) {
    /*This method is rerun every time setState is called, for instance as done
    by the _incrementCounter method above.
    每次调用setState时都会重新运行这个方法,例如上面的_incrementCounter方法。

    The Flutter framework has been optimized to make rerunning build methods
    fast, so that you can just rebuild anything that needs updating rather
    than having to individually change instances of widgets.
    Flutter框架经过优化,可以快速重新运行构建方法,这样你就可以重新构建任何需要更新的东西,而不必单独更改部件实例。
    */
    return Scaffold(
      appBar: AppBar(
        /*TRY THIS: Try changing the color here to a specific color (to
        Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
        change color while the other colors stay the same.
        试试这个:尝试将这里的颜色更改为特定的颜色(到Colors。可能是琥珀色?),并触发热重载,以看到应用栏改变颜色,而其他颜色保持不变。
        */
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        /*Here we take the value from the MyHomePage object that was created by
        the App.build method, and use it to set our appbar title.
        这里,我们从App.build方法创建的MyHomePage对象中获取值,并使用它来设置appbar标题。
        */
        title: Text(widget.title),
      ),
      body: Center(
        /*Center is a layout widget. It takes a single child and positions it
        in the middle of the parent.
        Center是一个布局部件。它接收一个子元素,并将其放置在父元素的中间。
        */
        child: Column(
          /*Column is also a layout widget. It takes a list of children and
          arranges them vertically. By default, it sizes itself to fit its
          children horizontally, and tries to be as tall as its parent.
          Column也是一个布局部件。它接收一个子元素列表,并将它们垂直排列。
          默认情况下,它会调整自己的大小以适应它的子元素,并尽量与父元素一样高。

          Column has various properties to control how it sizes itself and
          how it positions its children. Here we use mainAxisAlignment to
          center the children vertically; the main axis here is the vertical
          axis because Columns are vertical (the cross axis would be horizontal).
          列有各种属性来控制它自己的大小以及子元素的位置。这里我们使用mainAxisAlignment来让子元素垂直居中;
          这里的主轴是纵轴,因为列是垂直的(交叉轴是水平的)。

          TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
          action in the IDE, or press "p" in the console), to see the
          wireframe for each widget.
          试试这个:调用“debug painting”(在IDE中选择“Toggle debug Paint”操作,或者在控制台中按“p”),以查看每个部件的线框。
          */
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods。末尾的逗号使构建方法的自动格式化更好。.
    );
  }
}

4、必看电子书:《Flutter实战·第二版》

5、必看官方例子❌

你可以进入github,然后搜索flutter。
你会看到:
在这里插入图片描述>推荐多下几个例子过来跑跑。再多看看书,多思考实践。基本就知道使用Flutter了。
在这里插入图片描述
打开导入的项目,可能需要配置Dart和Flutter路径。
在这里插入图片描述在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/942123.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从项目中突显技能:在面试中讲述你的编程故事

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

华为数通方向HCIP-DataCom H12-821题库(单选题:141-160)

第141题 Router-LSA 能够描述不同的链路类型&#xff0c;不属于Router LSA 链路类型的是以下哪一项? A、Link Type 可以用来描述到末梢网络的连接&#xff0c;即 SubNet B、Link Type 可以用来描述到中转网络的连接&#xff0c;即 TranNet C、Link Type 可以用来描述到另一…

16.CSS菜单悬停特效

效果 源码 <!DOCTYPE html> <html> <head> <title>Creative Menu Item Hover Effects</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body><section><…

Vue项目中app.js过大,导致web初始化加载过慢问题

1、删除多余不需要的库&#xff1a; npm uninstall xxx 如例如moment库文件是很大的可以直接放到index.html文件直接CDN引入 2、修改/config/index.js配置文件&#xff1a;将productionGzip设置为false ​ 3、设置vue-router懒加载 懒加载配置&#xff1a; ​ 非懒加载配置&…

winpe使用AOMEI Backupper备份磁盘和操作系统

winpe系统说明 我们可以将winpe制作成再u盘启动&#xff1b; 我们可以在winpe上安装备份磁盘和操作的软件AOMEI Backupper&#xff1b; 磁盘备份和系统备份软件 AOMEI Backupper 直接双击exe即可 选择磁盘备份 点击添加磁盘 选择磁盘&#xff0c;点击添加 点击开始备份&…

django中使用websocket

python本身只支持http协议 使用websocket需要下载第三方库 pip install -U channels 需要在seting.py里配置&#xff0c;将我们的channels加入INSTALLED_APP里。 INSTALLED_APPS ( django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, …

扩散模型实战(七):Diffusers蝴蝶图像生成实战

推荐阅读列表&#xff1a; 扩散模型实战&#xff08;一&#xff09;&#xff1a;基本原理介绍 扩散模型实战&#xff08;二&#xff09;&#xff1a;扩散模型的发展 扩散模型实战&#xff08;三&#xff09;&#xff1a;扩散模型的应用 扩散模型实战&#xff08;四&#xf…

ASUS华硕天选4笔记本电脑FA507XV原厂Windows11系统22H2

天选四FA507X原装系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件 华硕电脑管家、奥创控制中心等预装程序&#xff0c;恢复出厂状态W11 链接&#xff1a;https://pan.baidu.com/s/1SPoFW7wR5KawGu-yMckNzg?pwdayxd 提取码&#xff1a;ayxd

听会议整理的几个问题整理

听会议整理的几个问题整理 AR与NAR正样本和负样本数据蒸馏 AR与NAR 正样本和负样本 对于ar 和nar ar虽然从一个人来看是串行的&#xff0c;但是可以对用户进行并行 nar对于一个人的需求是并行的。但是对于多用户是无法并行的 所以ar并非一定效率低 数据蒸馏

CUDA小白 - NPP(2) -图像处理-算数和逻辑操作

cuda小白 原文链接 NPP GPU架构近些年也有不少的变化&#xff0c;具体的可以参考别的博主的介绍&#xff0c;都比较详细。还有一些cuda中的专有名词的含义&#xff0c;可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》 常见的NppStatus&#xff0c…

手机无人直播软件有哪些,又有哪些优势?

如今&#xff0c;随着智能手机的普及和移动互联网的发展&#xff0c;手机无人直播成为了一个炙手可热的领域。手机无人直播软件为用户提供了便捷、灵活的直播方式&#xff0c;让更多商家人能够实现自己的直播带货的梦想。接下来&#xff0c;我们将探讨手机无人直播软件有哪些&a…

解密算法与数据结构面试:程序员如何应对挑战

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

el-upload调用内部方法删除文件

从Element UI 的官方文档中&#xff0c; Upload 上传组组件提供了on-remove和before-remove的文件删除的钩子属性&#xff08;回调方法名&#xff09;&#xff0c;但如何调用组件删除方法&#xff08;让该方法删除本地上传文件列表以及触发这两个钩子&#xff09;并无相关说明。…

解锁安全高效办公——私有化部署的WorkPlus即时通讯软件

在当今信息时代&#xff0c;高效的沟通与协作对于企业的成功至关重要。然而&#xff0c;随着信息技术的发展&#xff0c;保护敏感信息和数据安全也变得越来越重要。为了满足企业对于安全沟通和高效办公的需求&#xff0c;我们隆重推出私有化部署的WorkPlus即时通讯软件&#xf…

Marin说PCB之如何使用CAM350做Gerber compare ?

最近小编在追一部东北武侠喜剧&#xff08;鹊刀门传奇&#xff09;&#xff0c;大部分人员都是乡村爱情的人员演的&#xff0c;这部剧真的是超级搞笑&#xff0c;小编我以人格担保要是不搞笑的话&#xff0c;你来找我。 正当小编我周日在家里追剧的时候&#xff0c;手机上弹出了…

Git仓库简介

1、工作区、暂存区、仓库 工作区&#xff1a;电脑里能看到的目录。 暂存区&#xff1a;工作区有一个隐藏目录.git&#xff0c;是Git的版本库&#xff0c;Git的版本库里存了很多东西&#xff0c;其中最重要的就是称为stage&#xff08;或者叫index&#xff09;的暂存区&#xf…

【技术】SpringBoot Word 模板替换

SpringBoot Word 模板替换 什么是 Word 模板替换如何实现 Word 模板替换 什么是 Word 模板替换 模板一般是具有固定格式的内容&#xff0c;其中一部分需要替换。Word 模板通俗的讲是以 Word 的形式制作模板&#xff0c;固定格式和内容&#xff0c;然后将其中的一部分数据替换掉…

第 1 章 绪论 (三元组)

1. 示例代码&#xff1a; 1&#xff09;status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H/* 函数结果状态码 */ #define TRUE 1 /* 返回值为真 */ #define FALSE 0 /* 返回值为假 */ #define RET_OK 0 /* 返回值…

电脑不安装软件,怎么将手机文件传输到电脑?

很多人都知道&#xff0c;AirDroid有网页版&#xff08;web.airdroid.com&#xff09;。 想要文件传输&#xff0c;却不想在电脑安装软件时&#xff0c;AirDroid的网页版其实也可以传输文件。 然而&#xff0c;要将文件从手机传输文件到网页端所在的电脑时&#xff0c;如果按…

Vue05_关于插槽和指令封装的运用

Vue_05 文章目录 Vue_05Vue 插槽01-插槽-默认插槽默认插槽-基本语法 02-插槽-后备内容&#xff08;默认值&#xff09;默认值设置方法 03-插槽-具名插槽具名插槽-语法 04-插槽-作用域插槽默认插槽-语法代码示例 Vue自定义指令- v-loading封装01-自定义指令自定义指令的两种注册…