Flutter常用功能教程:新手入门指南

打印 上一主题 下一主题

主题 1819|帖子 1819|积分 5457

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Flutter常用功能教程

本文提供了具体的Flutter常用功能教程,涵盖环境搭建、布局与UI设计、导航与路由管理、状态管理入门、数据获取与网络哀求以及生存用户数据等内容,帮助开发者快速上手Flutter开发
Flutter简介及环境搭建

Flutter是什么

Flutter是Google开发的一套开源UI软件开发工具包,支持创建高性能、美观的原生应用步调,可在iOS和Android上运行。Flutter使用Dart语言编写,可以利用它的热重载特性快速迭代开发
开发环境搭建步骤

安装Flutter SDK


  • 下载Flutter SDK:访问Flutter官网,下载适合的利用系统版本。
  • 解压下载的SDK包到安装目次。
安装Dart SDK

Flutter依赖于Dart语言,因此你必要安装Dart SDK。

  • 下载并安装Dart SDK。
  • 设置环境变量:将Dart SDK的bin目次添加到系统PATH中。
设置Android环境


  • 安装Android Studio并设置Android SDK。
  • 安装Android SDK命令行工具、Android SDK Platform-Tools以及Android SDK Build-Tools。
  • 设置环境变量:将Android SDK的路径添加到系统PATH中。
设置iOS环境

对于Mac用户:

  • 安装Xcode。
  • 设置环境变量:将Xcode的路径添加到系统PATH中。
对于Windows/Linux用户:

  • 由于Flutter目前不支持在Windows/Linux上直接开发iOS应用,因此必要借助模拟器大概Mac机器。
安装Flutter命令行工具


  • 安装Flutter命令行工具,确保Flutter命令行工具位于PATH环境变量中。
  • 运行flutter doctor命令,查抄是否安装成功并设置正确。
创建Flutter环境

创建Flutter环境通常必要以下步骤:

  • 初始化Flutter环境:在命令行输入flutter doctor,确保安装的Flutter版本和环境设置无误。
  • 创建Flutter项目:使用flutter create project_name命令创建一个新的Flutter项目。
第一个Flutter项目创建

创建一个新的Flutter项目,起首在命令行中运行以下命令:
  1. flutter create first_flutter_app
复制代码
这将创建一个新的目次first_flutter_app,其中包含项目标基本布局。
项目布局

创建的项目布局大抵如下:
  1. first_flutter_app/
  2. ├── android/
  3. ├── ios/
  4. ├── lib/
  5. │   └── main.dart
  6. ├── pubspec.yaml
  7. └── test/
复制代码
运行项目

运行项目可以使用以下命令:
  1. cd first_flutter_app
  2. flutter run
复制代码
这将启动默认的模拟器或毗连的装备并运行应用。
布局与UI设计

常用布局组件介绍

Container

Container是最常用的布局组件,可以设置背景颜色、边框、内边距等。它是其他组件的基础。
  1. Container(
  2.   color: Colors.blue,
  3.   padding: EdgeInsets.all(16),
  4.   child: Text("Hello World"),
  5. )
复制代码
Column

Column用于垂直排列子组件,子组件会依次从上到下排列。
  1. Column(
  2.   children: [
  3.     Text("Row 1"),
  4.     Text("Row 2"),
  5.     Text("Row 3"),
  6.   ],
  7. )
复制代码
Row

Row用于水平排列子组件,子组件会依次从左到右排列。
  1. Row(
  2.   children: [
  3.     Text("Column 1"),
  4.     Text("Column 2"),
  5.     Text("Column 3"),
  6.   ],
  7. )
复制代码
Stack

Stack用于在二维空间中重叠多个子组件,可以设置子组件的位置。
  1. Stack(
  2.   children: [
  3.     Positioned(
  4.       top: 0,
  5.       left: 0,
  6.       child: Container(
  7.         width: 50,
  8.         height: 50,
  9.         color: Colors.red,
  10.       ),
  11.     ),
  12.     Positioned(
  13.       top: 100,
  14.       left: 100,
  15.       child: Container(
  16.         width: 50,
  17.         height: 50,
  18.         color: Colors.green,
  19.       ),
  20.     ),
  21.   ],
  22. )
复制代码
ListView

ListView用于创建可滚动的列表,可以垂直滚动或水平滚动。
  1. ListView(
  2.   children: [
  3.     ListTile(
  4.       title: Text("Item 1"),
  5.     ),
  6.     ListTile(
  7.       title: Text("Item 2"),
  8.     ),
  9.     ListTile(
  10.       title: Text("Item 3"),
  11.     ),
  12.   ],
  13. )
复制代码
Expanded

Expanded用于在Column或Row中分配剩余的空间给子组件。
  1. Column(
  2.   children: [
  3.     Text("Fixed Size"),
  4.     Expanded(
  5.       child: Text("Expand to fill space"),
  6.     ),
  7.   ],
  8. )
复制代码
布局实战:创建一个简单的登录界面

登录界面通常包含输入框、按钮等组件。下面我们将使用Flutter框架创建一个简单的登录界面。
创建登录界面布局

  1. import 'package:flutter/material.dart';
  2. void main() {
  3.   runApp(MyApp());
  4. }
  5. class MyApp extends StatelessWidget {
  6.   @override
  7.   Widget build(BuildContext context) {
  8.     return MaterialApp(
  9.       title: 'Login Demo',
  10.       home: LoginPage(),
  11.     );
  12.   }
  13. }
  14. class LoginPage extends StatefulWidget {
  15.   @override
  16.   _LoginPageState createState() => _LoginPageState();
  17. }
  18. class _LoginPageState extends State<LoginPage> {
  19.   final TextEditingController _usernameController = TextEditingController();
  20.   final TextEditingController _passwordController = TextEditingController();
  21.   void _login() {
  22.     // 登录逻辑
  23.     print(_usernameController.text);
  24.     print(_passwordController.text);
  25.   }
  26.   @override
  27.   Widget build(BuildContext context) {
  28.     return Scaffold(
  29.       appBar: AppBar(
  30.         title: Text('Login'),
  31.       ),
  32.       body: Padding(
  33.         padding: EdgeInsets.all(16),
  34.         child: Column(
  35.           children: [
  36.             TextField(
  37.               controller: _usernameController,
  38.               decoration: InputDecoration(
  39.                 labelText: 'Username',
  40.               ),
  41.             ),
  42.             TextField(
  43.               controller: _passwordController,
  44.               obscureText: true,
  45.               decoration: InputDecoration(
  46.                 labelText: 'Password',
  47.               ),
  48.             ),
  49.             SizedBox(height: 16),
  50.             ElevatedButton(
  51.               onPressed: _login,
  52.               child: Text('Login'),
  53.             ),
  54.           ],
  55.         ),
  56.       ),
  57.     );
  58.   }
  59. }
复制代码
导航与路由管理

Flutter中的导航机制

Flutter使用Navigator来管理页面的导航。每个页面都是一个路由,通过Navigator可以实现页面的切换。
页面跳转

使用Navigator.push方法可以实现页面的跳转。
  1. Navigator.push(
  2.   context,
  3.   MaterialPageRoute(builder: (context) => NewPage()),
  4. )
复制代码
返回页面

使用Navigator.pop方法可以实现页面的返回。
  1. Navigator.pop(context);
复制代码
使用定名路由

为每个路由提供一个名称,可以方便地管理和跳转。
  1. // 定义路由名称
  2. final String routeName = '/new-page';
  3. // 跳转到命名路由
  4. Navigator.pushNamed(context, routeName);
复制代码
创建简单的导航应用

我们将创建一个简单的导航应用,包含主页和详情页。
创建主页

  1. import 'package:flutter/material.dart';
  2. void main() {
  3.   runApp(MyApp());
  4. }
  5. class MyApp extends StatelessWidget {
  6.   @override
  7.   Widget build(BuildContext context) {
  8.     return MaterialApp(
  9.       title: 'Navigation Demo',
  10.       initialRoute: '/',
  11.       routes: {
  12.         '/': (context) => HomePage(),
  13.         '/detail': (context) => DetailPage(),
  14.       },
  15.     );
  16.   }
  17. }
  18. class HomePage extends StatelessWidget {
  19.   @override
  20.   Widget build(BuildContext context) {
  21.     return Scaffold(
  22.       appBar: AppBar(
  23.         title: Text('Home'),
  24.       ),
  25.       body: Center(
  26.         child: ElevatedButton(
  27.           onPressed: () {
  28.             Navigator.pushNamed(context, '/detail');
  29.           },
  30.           child: Text('Go To Detail'),
  31.         ),
  32.       ),
  33.     );
  34.   }
  35. }
复制代码
创建详情页

  1. class DetailPage extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text('Detail'),      ),      body: Center(        child: ElevatedButton(          onPressed: () {            Navigator.pop(context);
  2.           },          child: Text('Back To Home'),        ),      ),    );  }}
复制代码
状态管理入门

状态管理的重要性

在Flutter开发中,状态管理是处理应用状态变更的关键。通过状态管理,可以实现组件状态更新、数据同步等功能。精良的状态管理可以提升应用性能,改善用户体验。
常见状态管理方案


  • Provider : 简单高效的状态管理,基于Provider库实现。
  • BLoC : 业务逻辑组件,适用于复杂状态管理需求。
  • Riverpod : Provider的替代品,提供了更多的功能和灵活性。
使用Provider进行状态管理

Provider是一种简单高效的状态管理方案,适用于大多数应用的状态管理需求。
基本使用

起首,定义一个状态类。
  1. import 'package:flutter/material.dart';
  2. class CounterModel with ChangeNotifier {
  3.   int counter = 0;
  4.   void increment() {
  5.     counter++;
  6.     notifyListeners();
  7.   }
  8. }
复制代码
提供状态

使用Provider提供状态。
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. void main() {
  4.   runApp(
  5.     MultiProvider(
  6.       providers: [
  7.         ChangeNotifierProvider(
  8.           create: (context) => CounterModel(),
  9.         ),
  10.       ],
  11.       child: MyApp(),
  12.     ),
  13.   );
  14. }
  15. class MyApp extends StatelessWidget {
  16.   @override
  17.   Widget build(BuildContext context) {
  18.     return MaterialApp(
  19.       title: 'Provider Demo',
  20.       home: HomeScreen(),
  21.     );
  22.   }
  23. }
复制代码
消费状态

在必要使用状态的地方,通过Consumer获取状态。
  1. class HomeScreen extends StatelessWidget {
  2.   @override
  3.   Widget build(BuildContext context) {
  4.     return Scaffold(
  5.       appBar: AppBar(
  6.         title: Text('Provider'),
  7.       ),
  8.       body: Center(
  9.         child: Consumer<CounterModel>(
  10.           builder: (context, model, child) {
  11.             return Text(
  12.               '${model.counter}',
  13.               style: Theme.of(context).textTheme.headline1,
  14.             );
  15.           },
  16.         ),
  17.       ),
  18.       floatingActionButton: FloatingActionButton(
  19.         onPressed: () {
  20.           context.read<CounterModel>().increment();
  21.         },
  22.         tooltip: 'Increment',
  23.         child: Icon(Icons.add),
  24.       ),
  25.     );
  26.   }
  27. }
复制代码
复杂场景示例

在复杂场景中,Provider可以处理异步状态更新或状态更新的连锁反应。例如,当数据从服务器获取后更新UI,大概多个组件必要协同更新状态。
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import 'package:dio/dio.dart';
  4. class AsyncCounterModel with ChangeNotifier {
  5.   bool _isLoading = false;
  6.   int _counter = 0;
  7.   bool get isLoading => _isLoading;
  8.   int get counter => _counter;
  9.   Future<void> fetchCounter() async {
  10.     _isLoading = true;
  11.     notifyListeners();
  12.     final dio = Dio();
  13.     final response = await dio.get('https://api.example.com/counter');
  14.     if (response.statusCode == 200) {
  15.       _counter = response.data['counter'];
  16.       _isLoading = false;
  17.       notifyListeners();
  18.     } else {
  19.       _isLoading = false;
  20.       notifyListeners();
  21.     }
  22.   }
  23. }
  24. void main() {
  25.   runApp(
  26.     MultiProvider(
  27.       providers: [
  28.         ChangeNotifierProvider(
  29.           create: (context) => AsyncCounterModel(),
  30.         ),
  31.       ],
  32.       child: MyApp(),
  33.     ),
  34.   );
  35. }
  36. class MyApp extends StatelessWidget {
  37.   @override
  38.   Widget build(BuildContext context) {
  39.     return MaterialApp(
  40.       title: 'Provider Demo',
  41.       home: HomeScreen(),
  42.     );
  43.   }
  44. }
  45. class HomeScreen extends StatelessWidget {
  46.   @override
  47.   Widget build(BuildContext context) {
  48.     return Scaffold(
  49.       appBar: AppBar(
  50.         title: Text('Provider'),
  51.       ),
  52.       body: Center(
  53.         child: Consumer<AsyncCounterModel>(
  54.           builder: (context, model, child) {
  55.             return Column(
  56.               mainAxisAlignment: MainAxisAlignment.center,
  57.               children: [
  58.                 Text(
  59.                   model.isLoading ? 'Loading...' : '${model.counter}',
  60.                   style: Theme.of(context).textTheme.headline1,
  61.                 ),
  62.                 SizedBox(height: 16),
  63.                 ElevatedButton(
  64.                   onPressed: model.isLoading ? null : model.fetchCounter,
  65.                   child: Text('Fetch Counter'),
  66.                 ),
  67.               ],
  68.             );
  69.           },
  70.         ),
  71.       ),
  72.       floatingActionButton: FloatingActionButton(
  73.         onPressed: () {
  74.           context.read<AsyncCounterModel>().fetchCounter();
  75.         },
  76.         tooltip: 'Fetch Counter',
  77.         child: Icon(Icons.refresh),
  78.       ),
  79.     );
  80.   }
  81. }
复制代码
数据获取与网络哀求

HTTP哀求基础

HTTP哀求是网络通讯的基础,Flutter中可以使用Dio库或HttpClient来实现HTTP哀求。
安装Dio

在pubspec.yaml文件中添加Dio依赖:
  1. dependencies:
  2.   dio: ^4.0.0
复制代码
发送GET哀求(Dio)

  1. import 'package:dio/dio.dart';
  2. Future<void> fetchUser() async {
  3.   final dio = Dio();
  4.   final response = await dio.get('https://api.github.com/users/flutter');
  5.   if (response.statusCode == 200) {
  6.     print(response.data);
  7.   } else {
  8.     print('Request failed with status code: ${response.statusCode}');
  9.   }
  10. }
复制代码
发送POST哀求(Dio)

  1. import 'package:dio/dio.dart';
  2. Future<void> createUser() async {
  3.   final dio = Dio();
  4.   final response = await dio.post('https://api.example.com/users', data: {
  5.     'name': 'John Doe',
  6.     'email': 'john@example.com',
  7.   });
  8.   if (response.statusCode == 201) {
  9.     print(response.data);
  10.   } else {
  11.     print('Request failed with status code: ${response.statusCode}');
  12.   }
  13. }
复制代码
发送GET哀求(HttpClient)

  1. import 'dart:convert';
  2. import 'dart:io';
  3. Future<void> fetchUser() async {
  4.   final httpClient = HttpClient();
  5.   final request = await httpClient.getUrl(Uri.parse('https://api.github.com/users/flutter'));
  6.   final response = await request.close();
  7.   if (response.statusCode == HttpStatus.ok) {
  8.     final data = json.decode(await response.transform(utf8.decoder).join());
  9.     print(data);
  10.   } else {
  11.     print('Request failed with status code: ${response.statusCode}');
  12.   }
  13. }
复制代码
发送POST哀求(HttpClient)

  1. import 'dart:convert';
  2. import 'dart:io';
  3. Future<void> createUser() async {
  4.   final httpClient = HttpClient();
  5.   final request = await httpClient.postUrl(Uri.parse('https://api.example.com/users'));
  6.   request.headers.contentType = ContentType.json;
  7.   request.add(json.encode({'name': 'John Doe', 'email': 'john@example.com'}));
  8.   final response = await request.close();
  9.   if (response.statusCode == HttpStatus.created) {
  10.     final data = json.decode(await response.transform(utf8.decoder).join());
  11.     print(data);
  12.   } else {
  13.     print('Request failed with status code: ${response.statusCode}');
  14.   }
  15. }
复制代码
使用Dio进行网络哀求

Dio是一个功能强大的HTTP客户端库,支持各种网络哀求,并且具有丰富的设置选项。
基本设置

  1. import 'package:dio/dio.dart';
  2. void main() {
  3.   final dio = Dio();
  4.   dio.options.baseUrl = 'https://api.example.com';
  5.   dio.options.connectTimeout = 5000; // 5秒超时
  6.   dio.interceptors.add(
  7.     InterceptorsWrapper(
  8.       onRequest: (options, handler) {
  9.         print('Requesting: ${options.method} ${options.path}');
  10.         handler.next(options);
  11.       },
  12.       onResponse: (response, handler) {
  13.         print('Response: ${response.statusCode}');
  14.         handler.next(response);
  15.       },
  16.       onError: (error, handler) {
  17.         print('Error: ${error.message}');
  18.         handler.next(error);
  19.       },
  20.     ),
  21.   );
  22.   // 使用dio发送GET请求
  23.   fetchUser().then((_) => print('User fetched successfully'));
  24. }
  25. Future<void> fetchUser() async {
  26.   final response = await dio.get('/users');
  27.   if (response.statusCode == 200) {
  28.     print(response.data);
  29.   } else {
  30.     throw Exception('Failed to fetch user');
  31.   }
  32. }
复制代码
文件上传

  1. import 'dart:io';
  2. import 'package:dio/dio.dart';
  3. void main() {
  4.   final dio = Dio();
  5.   final file = File('/path/to/file');
  6.   FormData formData = FormData.fromMap({
  7.     'file': await MultipartFile.fromFile(file.path),
  8.   });
  9.   final response = await dio.post('https://api.example.com/upload', data: formData);
  10.   if (response.statusCode == 201) {
  11.     print(response.data);
  12.   } else {
  13.     throw Exception('Failed to upload file');
  14.   }
  15. }
复制代码
错误处理

  1. import 'package:dio/dio.dart';
  2. Future<void> fetchUser() async {
  3.   try {
  4.     final response = await dio.get('/users');
  5.     if (response.statusCode == 200) {
  6.       print(response.data);
  7.     } else {
  8.       throw Exception('Request failed with status code: ${response.statusCode}');
  9.     }
  10.   } catch (error) {
  11.     print('Error: ${error.toString()}');
  12.   }
  13. }
复制代码
生存用户数据

Flutter中存储数据的方法

Flutter提供了多种存储数据的方式,包括SharedPreferences、SQLite数据库、Hive等。
SharedPreferences

SharedPreferences用于生存简单范例的键值对数据,如字符串、整数、布尔值等。
使用SharedPreferences进行数据恒久化

起首,在pubspec.yaml文件中添加shared_preferences依赖:
  1. dependencies:
  2.   shared_preferences: ^2.0.6
复制代码
读取数据

  1. import 'package:shared_preferences/shared_preferences.dart';
  2. Future<void> readData() async {
  3.   final prefs = await SharedPreferences.getInstance();
  4.   final name = prefs.getString('name');
  5.   final age = prefs.getInt('age');
  6.   print('Name: $name, Age: $age');
  7. }
复制代码
写入数据

  1. import 'package:shared_preferences/shared_preferences.dart';
  2. Future<void> writeData
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表