Flutter的第一个Demo和Bug

文章目录

  • [1. Flutter开发环境配置](#1. Flutter开发环境配置)
  • [2. 第一个Demo](#2. 第一个Demo)
  • [3. 第一个bug](#3. 第一个bug)
    • [3.1 No Directionality widget found](#3.1 No Directionality widget found)

1. Flutter开发环境配置

注意,初学者可参照Flutter中文官网慢慢摸索,这里总结如下:

1、下载最新版的Android Studio,在AS的plugin市场中安装最新的flutter和dart插件。

关于AS和Java等相关环境变量的配置自行搜索吧。

2、去Git官网安装最新的git,并添加到环境变量。否则第5条中的部分命令会失效。

3、去Flutter官网下载最新的Flutter SDK,下载完成后直接解压,并将解压后的文件存放到自己的开发目录。

例如,我将其存放在:D:\ProgramFiles\Flutter目录中。

注意,需要将flutter的bin目录添加到环境变量中(见上图)。

4、Flutter SDK内置Dart SDK,故无须额外配置Dart开发环境。

5、打开git的GUI或者在AS的Terminal中运行以下命令,以便检测配置工作是否正确完成:

java 复制代码
/*
 flutter --version
 
 dart --version
 
 flutter doctor
*/

6、至此,Flutter配置工作结束,可用AS新建Flutter项目开始编码了(要选择New Flutter Project哦)。

但是,打开AS第一次新建Flutter项目时会要求选择Flutter SDK所在目录,在AS界面中选择flutter的存放路径即可。如

2. 第一个Demo

用AS新建一个Flutter项目,系统会生成默认Demo。

注意,Flutter项目名只能是lower_case_with_underscrores,即只能是小写和下划线。

项目结构如下图:

lib/main.dart是程序入口,类似AS项目的MainActivity。

flutter的项目代码存放在lib目录中,类似AS项目的app/src/main目录。

系统默认的main.dart的代码如下(已删除默认注释):

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp()); //runApp()是系统函数
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
  	  // MaterialApp()也是系统函数,有Directionality
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        
        colorScheme: .fromSeed(seedColor: Colors.deepPurple),
      ),
      // 将home实例替换为自己的Demo,否则会产生第一个bug
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: .center,
          children: [
            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),
      ),
    );
  }
}

新建AS模拟器或连接真机即可运行该Demo,效果图如下:

右上角的debug是调试标志,因为MaterialApp(xxx)函数的默认属性this.debugShowCheckedModeBanner = true,手动修改该属性为false就没有debug标志了。

3. 第一个bug

3.1 No Directionality widget found

接下来,新建自己的demo,如新建ContainerPage.dart:

dart 复制代码
import 'package:flutter/material.dart';

class ContainerPage extends StatelessWidget {
  const ContainerPage({super.key});

  /// 上层调用必须有Directionality,否则报错:No Directionality widget found.
  @override
  Widget build(BuildContext context) {
    // Scaffold无Directionality
    return Scaffold(
      appBar: AppBar(title: const Text("Container")),
      body: Container(
        margin: const EdgeInsets.only(top: 50.0, left: 120.0),
        constraints: const BoxConstraints.tightFor(
          width: 200.0,
          height: 200.0,
        ),
        decoration: const BoxDecoration(
          gradient: RadialGradient(
            colors: [Colors.red, Colors.orange],
            center: Alignment.topLeft,
            radius: .98,
          ),
          boxShadow: [
            BoxShadow(
              color: Colors.black54,
              offset: Offset(2.0, 2.0),
              blurRadius: 4.0,
            ),
          ],
        ),
        transform: Matrix4.rotationZ(.2),
        // 卡片倾斜变换
        alignment: Alignment.center,
        child: const Text(
          "520",
          style: TextStyle(color: Colors.white, fontSize: 40.0),
        ),
      ),
    );
  }

}

该Demo直接return Scaffold,而Scaffold没有Directionality,在main.dart中调用时需注意,若按下述方式调用会报错:No Directionality widget found.

dart 复制代码
import 'package:flutter/material.dart';
import 'package:flutter_xiangzhihong/ContainerPage.dart';

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

IDE报错信息:

真机运行页面报错信息:

正确的调用方式是 :

dart 复制代码
import 'package:flutter/material.dart';
import 'package:flutter_xiangzhihong/ContainerPage.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: .fromSeed(seedColor: Colors.deepPurple),
      ),
      // 替换原MyHomePage实例,因为MaterialApp有Directionality
      home: const ContainerPage(),
    );
  }
}

正常的运行结果:

参考文献:

1 向治洪.Flutter跨平台开发实战M.北京:清华大学出版社,2024

关注我:Accrual

相关推荐
iFlyCai1 小时前
Flutter三棵树核心详解之Element树完全解析(一)
flutter
天空之城--1 小时前
Android Flutter行业最新动态与实用参考(2026年8月第3周)
android·人工智能·flutter·ai编程
iFlyCai1 小时前
Flutter三棵树核心详解之Widget树完全解析(三)
flutter
iFlyCai10 小时前
Flutter三棵树核心详解之Widget树完全解析(一)
flutter
GitLqr14 小时前
Flutter 实战:如何轻松实现图片与视频保存到手机相册
flutter·全栈·dart
大龄秃头程序员15 小时前
【小记】第一次全栈踩坑 WebSocket 404
flutter
大龄秃头程序员19 小时前
Dart/Flutter StatefulWidget 生命周期 + ChangeNotifier Listener 泄漏的经典坑。
flutter
大龄秃头程序员21 小时前
Flutter踩坑记-WebSocket 通知挤占事件循环
flutter
恋猫de小郭1 天前
Gradle 9.7.0 将提速 Android 构建,Sync 提升接近一倍
android·前端·flutter