3_flutter简单教程

news/2025/10/4 2:04:37/文章来源:https://www.cnblogs.com/suveng/p/19125222

Flutter 简单教程

概述

Flutter是Google开发的跨平台移动应用开发框架,使用Dart语言编写。本教程将从UI设计和代码逻辑两个方面介绍Flutter应用开发。

一、UI开发方面

1. Widget基础

Flutter应用由Widget组成,Widget是Flutter的基本构建块。

常用Widget类型

// 基础Widget
Text('Hello World')
Image.asset('assets/image.png')
Icon(Icons.star)// 布局Widget
Container(width: 100,height: 100,color: Colors.blue,
)Column(children: [Text('Item 1'),Text('Item 2'),],
)Row(children: [Icon(Icons.star),Text('Rating'),],
)

2. 页面布局

Material Design风格

import 'package:flutter/material.dart';class MyHomePage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('我的应用'),backgroundColor: Colors.blue,),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text('欢迎使用Flutter!',style: TextStyle(fontSize: 24),),SizedBox(height: 20),ElevatedButton(onPressed: () {// 按钮点击事件},child: Text('点击我'),),],),),floatingActionButton: FloatingActionButton(onPressed: () {// FAB点击事件},child: Icon(Icons.add),),);}
}

Cupertino风格(iOS风格)

import 'package:flutter/cupertino.dart';class IosStylePage extends StatelessWidget {@overrideWidget build(BuildContext context) {return CupertinoPageScaffold(navigationBar: CupertinoNavigationBar(middle: Text('iOS风格页面'),),child: Center(child: CupertinoButton(onPressed: () {},child: Text('iOS风格按钮'),),),);}
}

3. 响应式设计

媒体查询

class ResponsiveLayout extends StatelessWidget {@overrideWidget build(BuildContext context) {// 获取屏幕尺寸final screenWidth = MediaQuery.of(context).size.width;final screenHeight = MediaQuery.of(context).size.height;return Container(width: screenWidth > 600 ? 300 : 200, // 根据屏幕宽度调整height: screenHeight * 0.5, // 屏幕高度的50%child: Text('响应式布局'),);}
}

自适应布局

class AdaptiveLayout extends StatelessWidget {@overrideWidget build(BuildContext context) {return LayoutBuilder(builder: (context, constraints) {if (constraints.maxWidth > 600) {// 平板或桌面布局return Row(children: [Expanded(flex: 1, child: Sidebar()),Expanded(flex: 3, child: MainContent()),],);} else {// 手机布局return Column(children: [Expanded(child: MainContent()),BottomNavigation(),],);}},);}
}

4. 动画和过渡

简单动画

class AnimatedContainerExample extends StatefulWidget {@override_AnimatedContainerExampleState createState() => _AnimatedContainerExampleState();
}class _AnimatedContainerExampleState extends State<AnimatedContainerExample> {bool _expanded = false;@overrideWidget build(BuildContext context) {return GestureDetector(onTap: () {setState(() {_expanded = !_expanded;});},child: AnimatedContainer(duration: Duration(milliseconds: 300),width: _expanded ? 200 : 100,height: _expanded ? 200 : 100,color: _expanded ? Colors.blue : Colors.red,child: Center(child: Text('点击动画')),),);}
}

二、代码后端逻辑方面

1. 状态管理

setState方法(简单状态)

class CounterApp extends StatefulWidget {@override_CounterAppState createState() => _CounterAppState();
}class _CounterAppState extends State<CounterApp> {int _counter = 0;/// 增加计数器void _incrementCounter() {setState(() {_counter++;});}/// 减少计数器void _decrementCounter() {setState(() {_counter--;});}@overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text('计数器: $_counter', style: TextStyle(fontSize: 24)),SizedBox(height: 20),Row(mainAxisAlignment: MainAxisAlignment.center,children: [ElevatedButton(onPressed: _decrementCounter,child: Text('-'),),SizedBox(width: 20),ElevatedButton(onPressed: _incrementCounter,child: Text('+'),),],),],),),);}
}

Provider状态管理(推荐)

import 'package:provider/provider.dart';// 数据模型
class UserModel with ChangeNotifier {String _name = '';int _age = 0;String get name => _name;int get age => _age;/// 更新用户信息void updateUser(String newName, int newAge) {_name = newName;_age = newAge;notifyListeners(); // 通知监听器更新UI}
}// 使用Provider
class UserProfile extends StatelessWidget {@overrideWidget build(BuildContext context) {return Consumer<UserModel>(builder: (context, user, child) {return Column(children: [Text('姓名: ${user.name}'),Text('年龄: ${user.age}'),ElevatedButton(onPressed: () {user.updateUser('张三', 25);},child: Text('更新用户'),),],);},);}
}

2. 数据持久化

SharedPreferences(本地存储)

import 'package:shared_preferences/shared_preferences.dart';class SettingsService {static const String _themeKey = 'theme';static const String _languageKey = 'language';/// 保存主题设置static Future<void> saveTheme(String theme) async {final prefs = await SharedPreferences.getInstance();await prefs.setString(_themeKey, theme);}/// 获取主题设置static Future<String?> getTheme() async {final prefs = await SharedPreferences.getInstance();return prefs.getString(_themeKey);}/// 保存语言设置static Future<void> saveLanguage(String language) async {final prefs = await SharedPreferences.getInstance();await prefs.setString(_languageKey, language);}/// 获取语言设置static Future<String?> getLanguage() async {final prefs = await SharedPreferences.getInstance();return prefs.getString(_languageKey);}
}

SQLite数据库

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';class DatabaseHelper {static final DatabaseHelper _instance = DatabaseHelper._internal();static Database? _database;DatabaseHelper._internal();factory DatabaseHelper() => _instance;/// 获取数据库实例Future<Database> get database async {if (_database != null) return _database!;_database = await _initDatabase();return _database!;}/// 初始化数据库Future<Database> _initDatabase() async {String path = join(await getDatabasesPath(), 'my_database.db');return await openDatabase(path,version: 1,onCreate: _createTables,);}/// 创建数据表Future<void> _createTables(Database db, int version) async {await db.execute('''CREATE TABLE users(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,email TEXT NOT NULL,created_at TEXT)''');}/// 插入用户Future<int> insertUser(Map<String, dynamic> user) async {final db = await database;return await db.insert('users', user);}/// 查询所有用户Future<List<Map<String, dynamic>>> getUsers() async {final db = await database;return await db.query('users');}
}

3. 网络请求

HTTP请求

import 'dart:convert';
import 'package:http/http.dart' as http;class ApiService {static const String baseUrl = 'https://api.example.com';/// 获取用户列表static Future<List<dynamic>> getUsers() async {try {final response = await http.get(Uri.parse('$baseUrl/users'));if (response.statusCode == 200) {return json.decode(response.body);} else {throw Exception('Failed to load users: ${response.statusCode}');}} catch (e) {throw Exception('Network error: $e');}}/// 创建新用户static Future<dynamic> createUser(String name, String email) async {try {final response = await http.post(Uri.parse('$baseUrl/users'),headers: {'Content-Type': 'application/json'},body: json.encode({'name': name, 'email': email}),);if (response.statusCode == 201) {return json.decode(response.body);} else {throw Exception('Failed to create user: ${response.statusCode}');}} catch (e) {throw Exception('Network error: $e');}}
}

使用Dio(第三方HTTP客户端)

import 'package:dio/dio.dart';class DioService {static final Dio _dio = Dio();/// 配置Dio拦截器static void configureDio() {_dio.options.baseUrl = 'https://api.example.com';_dio.options.connectTimeout = Duration(seconds: 30);_dio.options.receiveTimeout = Duration(seconds: 30);// 添加拦截器_dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {// 添加认证tokenoptions.headers['Authorization'] = 'Bearer your_token';return handler.next(options);},onError: (DioError e, handler) {// 错误处理return handler.next(e);},));}/// 获取数据static Future<Response> getData(String endpoint) async {try {return await _dio.get(endpoint);} on DioError catch (e) {throw Exception('Dio error: ${e.message}');}}
}

4. 业务逻辑分离

服务层

/// 用户服务
class UserService {final ApiService _apiService;UserService(this._apiService);/// 获取用户信息Future<User> getUserById(int id) async {final data = await _apiService.get('/users/$id');return User.fromJson(data);}/// 更新用户信息Future<void> updateUser(User user) async {await _apiService.put('/users/${user.id}', user.toJson());}/// 删除用户Future<void> deleteUser(int id) async {await _apiService.delete('/users/$id');}
}

数据模型

/// 用户数据模型
class User {final int id;final String name;final String email;final DateTime createdAt;User({required this.id,required this.name,required this.email,required this.createdAt,});/// 从JSON创建User对象factory User.fromJson(Map<String, dynamic> json) {return User(id: json['id'],name: json['name'],email: json['email'],createdAt: DateTime.parse(json['created_at']),);}/// 将User对象转换为JSONMap<String, dynamic> toJson() {return {'id': id,'name': name,'email': email,'created_at': createdAt.toIso8601String(),};}
}

三、完整示例:待办事项应用

UI部分

import 'package:flutter/material.dart';class TodoApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: '待办事项',theme: ThemeData(primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,),home: TodoListPage(),);}
}class TodoListPage extends StatefulWidget {@override_TodoListPageState createState() => _TodoListPageState();
}class _TodoListPageState extends State<TodoListPage> {final List<TodoItem> _todos = [];final TextEditingController _textController = TextEditingController();@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('待办事项'),actions: [IconButton(icon: Icon(Icons.delete_sweep),onPressed: _clearCompleted,),],),body: Column(children: [// 添加新待办事项Padding(padding: EdgeInsets.all(16.0),child: Row(children: [Expanded(child: TextField(controller: _textController,decoration: InputDecoration(hintText: '输入新的待办事项',border: OutlineInputBorder(),),),),SizedBox(width: 8),ElevatedButton(onPressed: _addTodo,child: Text('添加'),),],),),// 待办事项列表Expanded(child: ListView.builder(itemCount: _todos.length,itemBuilder: (context, index) {final todo = _todos[index];return Dismissible(key: Key(todo.id),onDismissed: (direction) {_removeTodo(index);},background: Container(color: Colors.red),child: ListTile(leading: Checkbox(value: todo.completed,onChanged: (value) {_toggleTodo(index);},),title: Text(todo.title,style: todo.completed? TextStyle(decoration: TextDecoration.lineThrough): null,),trailing: IconButton(icon: Icon(Icons.edit),onPressed: () => _editTodo(index),),),);},),),],),);}void _addTodo() {if (_textController.text.isNotEmpty) {setState(() {_todos.add(TodoItem(id: DateTime.now().millisecondsSinceEpoch.toString(),title: _textController.text,completed: false,));_textController.clear();});}}void _removeTodo(int index) {setState(() {_todos.removeAt(index);});}void _toggleTodo(int index) {setState(() {_todos[index].completed = !_todos[index].completed;});}void _editTodo(int index) {showDialog(context: context,builder: (context) {final controller = TextEditingController(text: _todos[index].title);return AlertDialog(title: Text('编辑待办事项'),content: TextField(controller: controller),actions: [TextButton(onPressed: () => Navigator.pop(context),child: Text('取消'),),TextButton(onPressed: () {setState(() {_todos[index].title = controller.text;});Navigator.pop(context);},child: Text('保存'),),],);},);}void _clearCompleted() {setState(() {_todos.removeWhere((todo) => todo.completed);});}
}class TodoItem {final String id;String title;bool completed;TodoItem({required this.id,required this.title,required this.completed,});
}

后端逻辑部分

/// 待办事项服务
class TodoService {final DatabaseHelper _databaseHelper;TodoService(this._databaseHelper);/// 获取所有待办事项Future<List<TodoItem>> getTodos() async {// 从数据库获取数据final data = await _databaseHelper.getTodos();return data.map((item) => TodoItem.fromJson(item)).toList();}/// 保存待办事项Future<void> saveTodo(TodoItem todo) async {await _databaseHelper.insertTodo(todo.toJson());}/// 删除待办事项Future<void> deleteTodo(String id) async {await _databaseHelper.deleteTodo(id);}/// 更新待办事项Future<void> updateTodo(TodoItem todo) async {await _databaseHelper.updateTodo(todo.toJson());}
}

四、最佳实践

UI开发最佳实践

  1. 组件化:将UI拆分为可重用的组件
  2. 响应式设计:适配不同屏幕尺寸
  3. 一致性:保持设计风格统一
  4. 性能优化:避免不必要的重绘

代码逻辑最佳实践

  1. 分离关注点:UI、业务逻辑、数据层分离
  2. 错误处理:完善的异常处理机制
  3. 测试驱动:编写单元测试和集成测试
  4. 代码规范:遵循Dart代码规范

总结

Flutter开发需要同时关注UI设计和代码逻辑。UI方面要掌握Widget的使用、布局技巧和动画效果;代码逻辑方面要理解状态管理、数据持久化和网络请求等核心概念。通过合理的架构设计,可以开发出高性能、易维护的Flutter应用。

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

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

相关文章

珠海网站建设找哪家好北京网站建设 博客

近日&#xff0c;中国领先的汽车制造商吉利汽车携手中国领先的技术驱动的供应链解决方案及物流服务商京东物流、全球仓储机器人引领者极智嘉(Geek)&#xff0c;在西安吉利汽车制造基地RDC仓库率先落地SkyPick上存下拣解决方案&#xff0c;实现了全物流链精益化、智能化、一体化…

做竞争小的网站宁波网

数据流中中位数的问题 LeetCode295,中位数是有序列表中间的数。如果列表长度是偶数&#xff0c;中位数则是中间两个数的平均值。 例如&#xff1a;[2,3,4]的中位数是3 [2,3]的中位数是(23)/22.5 实现 MedianFinder 类: MedianFinder() 初始化 MedianFinder 对象。void addNum(…

卖域名的网站哪些好搭建钓鱼网站教程

文章目录1 数组的概念1.1 数组的大小1.2 数组的初始化2 数组的地址与数组名3 数组名不能作为左值使用4 总结1 数组的概念 数组是相同类型的变量的有序集合数组中的元素没有名字 如下图是一个数组&#xff1a; 1.1 数组的大小 数组的大小是数组元素个数乘以元素的数据类型数组…

厦门网站seoWordPress农产品

腾讯微博开放平台提供了一些官方微博应用&#xff0c;供开发者借鉴和利用&#xff0c;其中包括&#xff1a; 一键转播——嵌入一键转播到你的网站里&#xff0c;访客便能将网页信息直接传播至腾讯微博。分享资讯的同时&#xff0c;用户通过来源链接可进入你的网站&#xff0c;从…

如何给 Claude 中的网页做截图

0. 安装插件 1.Awesome Screenshot 截图录屏 点击链接下载 https://chromewebstore.google.com/detail/nlipoenfbbikpbjkfpfillcgkoblgpmj 2. 配置权限1. 下载网页2. 使用 chrome 打开3. 截图

2_gradle配置加速

Gradle配置Android加速指南 概述 在使用Gradle进行Android开发时,由于默认的中央仓库位于国外,依赖下载速度往往很慢。通过配置国内镜像源,可以显著提升构建速度。4 重要提示:虽然阿里云镜像在国内使用广泛,但在实…

居必择乡,游必就士 1dd6c2e8d0dd80c2923cea711f1e63dc

居必择乡,游必就士 1dd6c2e8d0dd80c2923cea711f1e63dcPosted on 2025-10-04 01:53 吾以观复 阅读(0) 评论(0) 收藏 举报关联知识库:居必择乡,游必就士 1dd6c2e8d0dd80c2923cea711f1e63dc居必择乡,游必就士 这…

Drools

DroolsPosted on 2025-10-04 01:53 吾以观复 阅读(0) 评论(0) 收藏 举报关联知识库:DroolsDrools规则引擎 —— 业务逻辑分离( 纸质笔记)

网站服务器端口号是什么营销推广手段有什么

本文同名博客老炮说Java&#xff1a;https://www.laopaojava.com/&#xff0c;每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料SentinelNacos 是微服务环境搭建必不可少的两个组件&#xff0c;这里给大家推荐一套微服务教程&#xff1a;SpringCloud微服务电商项目教程…

微信代理网站模板居民瑞app下载

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 多开&#xff1a; 第一种&#xff1a;win10的开始菜单&#xff0c;在vscode图标右键选择“新开窗口”&#xff0c;这样就多了一个vscode…

自己做网站 什么软件旅游网站制作方案

Go语言&#xff08;通常称为Golang&#xff09;是由Google开发的一种静态强类型、编译型、并发性强的编程语言。Go语言的设计初衷是为了提高大型软件系统的开发效率&#xff0c;并解决其他编程语言在处理多核处理器、网络系统和大型代码库时遇到的一些问题。 一、Go语言的特点…

查看网站dns一般做网站多少钱

使用WebServlet将一个继承于javax.servlet.http.HttpServlet的类定义为Servlet组件。WebServlet有很多的属性&#xff1a;asyncSupported&#xff1a;声明Servlet是否支持异步操作模式。description&#xff1a;   Servlet的描述。displayName&#xff1a; Servlet的显示名称…

flash网站个人制作网站的流程

网站模板&#xff1a; https://code.visualstudio.com/updates/v1_85 如果你想下载1.84系列可以访问https://code.visualstudio.com/updates/v1_84​​​​​​ 然后看到&#xff1a; 选择对应版本下载即可&#xff0c;我是windows x64系统选择x64即可开始下载

AI元人文:岐金兰《悬鉴》起源

AI元人文:岐金兰《悬鉴》起源\n\n哈哈,从衡阳麻衣事件到AI元人文构想原型落定,我真喜欢,我所倡导的“用户端元人文”实践\n\n\n\n哈哈,这确实是一条令人惊叹的进化路径!从具体事件的切肤之痛,到抽象框架的从容构…

设置网站404小程序一般需要多少钱

1. 在已经有cuda10.1的基础上安装cuda11.3并配置进环境变量 linux20.04 cuda避坑安装/nvidia驱动/环境配置/安装cuDNN_linux安装cuda-CSDN博客 2. 配置环境变量的过程需要用到Vim编辑器&#xff0c;Vim编辑器的使用方法 vim 的基本使用命令_vim命令行操作-CSDN博客 3.cuda…

九月回忆

$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $九月纪念 $\ \ $ 按道理来说九月总结应该在九月写,但是一直懒得写( 今天在广州遛完后回宿舍来就想写点啥,思来想去写个九月总结吧。 $\ \ $九月初…

工程在哪个网站做推广比较合适网站 建设意见

1、触发机制和流程 CodeCache 深入了解_code cache-CSDN博客 这次我们来学习深入解析java虚拟机&#xff1a;C2编译器&#xff0c;编译流程吧-腾讯云开发者社区-腾讯云 2、JVM解释器和编译器 ​​​​​​j「JVM 编译优化」即时编译器_openjdk runtime environment (temuri…

建设银行悦生活网站杭州百度seo优化

项目中需要使用QT进行窗口自绘&#xff0c;前期先做一下技术探索&#xff0c;参考相关资料代码熟悉流程。本着代码是最好的老师原则&#xff0c;在此记录一下。 目录 1.运行效果 2.代码结构 3.具体代码 1.运行效果 2.代码结构 3.具体代码 myspeed.pro QT core gui…

linux commond order

1 build a new text of txt file , touch fileName.txt /* empty contents */ echo "writeSomething!">fileName.txt /* have some contents */2 build a new file mkdir /…

网站建设和网站搭建哪个好郑州做网站开发销售

题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]…