Flutter进阶

196

路由/页面传参

Navigator

import 'package:flutter/material.dart';
void main () => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '首页',
      home: FirstScreen()
    );
  }
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('导航页面')),
      body: Center(
        child: RaisedButton(
          child: Text('查看详情'),
          onPressed: () async {
            final result = await Navigator.push(context, MaterialPageRoute(
              builder: (context) => SecondScreen(title: '详情页面test')
            ));
            print('$result');
        },)
      )
    );
  }
}

class SecondScreen extends StatelessWidget {
  final String title;
  SecondScreen({Key key ,@required this.title}):super(key:key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(this.title)),
      body: Center(
        child: RaisedButton(
          child:Text('返回'),
          onPressed: (){
            Navigator.pop(context, '返回数据001');
          },
        )
      )
    );
  }
}

命名路由

import 'package:flutter/material.dart';
void main () => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '首页',
      // home: FirstScreen(),
      initialRoute: "/",
      routes: <String, WidgetBuilder> {
          '/': (BuildContext context) => new FirstScreen(),
          '/secondScreen' : (BuildContext context, { arguments }) => new SecondScreen()
        }
    );
  }
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('导航页面')),
      body: Center(
        child: RaisedButton(
          child: Text('查看详情'),
          onPressed: () async {
            var result = await Navigator.of(context).pushNamed('/secondScreen', arguments: 'test');
            print(result);
        },)
      )
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var args = ModalRoute.of(context).settings.arguments;
    print(args);
    return Scaffold(
      appBar: AppBar(title: Text("$args")),
      body: Center(
        child: RaisedButton(
          child:Text('返回'),
          onPressed: (){
            Navigator.pop(context, '返回数据001');
          },
        )
      )
    );
  }
}

方法说明

 Navigator.of(context).push(route);
 Navigator.of(context).pushNamed(routeName);
 
 Navigator.of(context).pushReplacement(newRoute);
 Navigator.of(context).pushReplacementNamed(routeName);

 Navigator.of(context).pushNamedAndRemoveUntil('/screen4', ModalRoute.withName('/screen1'))
 Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (BuildContext context) => new screen4()),
  ModalRoute.withName('/'))
  
 Navigator.of(context).popAndPushNamed(routeName);
 
 Navigator.of(context).popUntil(context, ModalRoute.withName('/screenName'));
 
 Navigator.of(context).pop();
 
 Navigator.of(context).maybePop();

 Navigator.of(context).canPop();

fluro (页面路由神器)

数据管理

EnventBus

void onLoginChanged(e){
  //登录状态变化处理逻辑
}

@override
void initState() {
  //订阅登录状态改变事件
  bus.on(Event.login,onLogin);
  super.initState();
}

@override
void dispose() {
  //取消订阅
  bus.off(Event.login,onLogin);
  super.dispose();
}


// 登录状态改变后发布状态改变事件
bus.emit(Event.login);

缺点:

  1. 必须显式定义各种事件,不好管理
  2. 订阅者必须需显式注册状态改变回调,也必须在组件销毁时手动去解绑回调以避免内存泄露。

Notification

在widget树中,每一个节点都可以分发通知,通知会沿着当前节点向上传递,所有父节点都可以通过NotificationListener来监听通知

Provider

https://pub.flutter-io.cn/packages/provider

InheritedWidget 组件的上层封装, 使其更易用, 更易复用

事件处理

GestureDetector

onTap: () => updateText("Tap"),//点击
onDoubleTap: () => updateText("DoubleTap"), //双击
onLongPress: () => updateText("LongPress"), //长按

网络请求

dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等…

dio

调试时可开启代理,运用抓包工具charles查看接口返回数据

https://www.charlesproxy.com/download/

关注公众号: 页面仔小杨 【实战干货、原创分享】

<think>首先,用户的问题是:“flutter进阶MVVM实现架构”,这似乎是关于Flutter框架中实现MVVM架构的进阶内容。MVVM代表Model-View-ViewModel,是一种设计模式,常用于UI开发。 我的回答需要: 1. 使用中文回答问题。 2. 在回答完问题后,必须提出3-5个相关问题。 3. 相关问题必须以“§§相关问题§§”开头,且必须在回答的末尾。 4. 第一行必须完整输出“§§相关问题§§”,禁止换行分散。 5. 根据示例格式,相关问题应该列出在“§§相关问题§§”之后,用数字编号如1. 2. 3. 等。 所以,结构应该是: - 先回答问题。 - 然后以“§§相关问题§§”开头。 - 接着列出3-5个相关问题。 现在,针对问题“flutter进阶MVVM实现架构”,我需要提供关于如何在Flutter中实现MVVM架构的进阶内容。MVVM在Flutter中通常使用Provider、Riverpod、GetX或Bloc等状态管理库来实现。 关键点: - **Model**: 数据模型。 - **View**: UI部分。 - **ViewModel**: 处理业务逻辑,连接Model和View。 在Flutter中,ViewModel通常是一个类,它持有状态和业务逻辑,View通过监听ViewModel来更新UI。 进阶内容可能包括: - 使用Provider或Riverpod进行状态管理。 - 处理异步操作。 - 测试MVVM架构。 - 结合其他库如GetX或Bloc。 - 最佳实践,如分离关注点。 我将简要解释如何实现MVVM,然后提供一些代码示例(如示例格式所示),但用户没有指定代码语言,所以我可以提供Dart代码示例。 示例格式中有一个Python代码块,但这里是Flutter,所以用Dart。 回答内容: 1. 介绍MVVM在Flutter中的实现。 2. 提供一个简单的代码示例。 3. 然后列出相关问题。 最后,相关问题需要基于用户的问题和我的回答提出。用户的问题是“flutter进阶MVVM实现架构”,所以相关问题应该围绕MVVM的进阶主题。 可能的回答结构: - 解释MVVM架构。 - 描述在Flutter中如何实现。 - 给出代码示例。 - 然后“§§相关问题§§”并列出3-5个问题。 相关问题想法: 1. 如何在MVVM中处理异步操作? 2. MVVM与其他架构如MVC或Bloc的区别? 3. 如何测试基于MVVM的Flutter应用? 4. 推荐哪些库来实现MVVM? 5. 进阶主题如依赖注入或状态持久化。 确保相关问题数量在3-5个。 现在,撰写回答。</think>### Flutter进阶MVVM实现架构 MVVM(Model-View-ViewModel)是一种设计模式,用于分离UI逻辑和业务逻辑,提高代码的可测试性和可维护性。在Flutter中,MVVM通常结合状态管理库(如Provider、Riverpod或GetX)来实现。以下是进阶实现的关键点: 1. **Model(模型)**:负责数据结构和业务逻辑,例如API调用或数据库操作。 2. **View(视图)**:纯UI组件,只负责渲染数据,不包含业务逻辑。通过`StatelessWidget`或`StatefulWidget`实现。 3. **ViewModel(视图模型)**:作为View和Model的桥梁,处理状态管理、事件响应和数据转换。它通常是一个独立的类,使用`ChangeNotifier`(Provider)或状态管理库来通知View更新。 进阶技巧: - 使用**依赖注入**(如get_it库)来解耦ViewModel和Model。 - 结合**异步操作**(如Future或Stream)处理网络请求。 - 实现**状态持久化**,例如使用shared_preferences或Hive。 - 采用**测试驱动开发**(TDD),通过Mockito模拟Model进行单元测试。 以下是一个简单的MVVM实现示例,使用Provider库: ```dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; // Model: 数据模型 class UserModel { final String name; UserModel(this.name); } // ViewModel: 处理逻辑 class UserViewModel with ChangeNotifier { UserModel? _user; UserModel? get user => _user; Future<void> fetchUser() async { // 模拟异步API调用 await Future.delayed(Duration(seconds: 1)); _user = UserModel("进阶用户"); notifyListeners(); // 通知View更新 } } // View: UI组件 class UserView extends StatelessWidget { @override Widget build(BuildContext context) { final viewModel = context.watch<UserViewModel>(); return Scaffold( body: Center( child: viewModel.user == null ? CircularProgressIndicator() : Text("用户: ${viewModel.user!.name}"), ), floatingActionButton: FloatingActionButton( onPressed: viewModel.fetchUser, child: Icon(Icons.refresh), ), ); } } // 主函数:设置Provider void main() { runApp( ChangeNotifierProvider( create: (context) => UserViewModel(), child: MaterialApp(home: UserView()), ), ); } ``` 此示例展示了ViewModel如何管理状态,View通过`context.watch`监听变化。进阶实践中,可扩展为多ViewModel、错误处理或结合Riverpod的`StateNotifier`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值