Flutter上下文引用插件context_ref的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter上下文引用插件context_ref的使用

context_ref简介

context_ref 是一个用于简化Flutter中上下文引用和状态管理的插件。它提供了一种更方便的方式替代 InheritedWidget,使得在Flutter应用中管理和访问状态变得更加简单。

context_ref.png

更多高级特性可以参考 context_plus

主要特性

  • Ref<T>:绑定到 context 的类型为 T 的值。
    • .bind(context, () => Value()):创建并绑定值到 context。当 context 被销毁时自动调用 dispose()
    • .bindLazy(context, () => Value()):与 .bind() 类似,但值仅在首次访问时创建。
    • .bindValue(context, value):绑定已创建的值到 context。值不会自动销毁。
    • .of(context):获取绑定到 context 或其最近祖先的值。

入门指南

添加依赖

首先,在项目的 pubspec.yaml 文件中添加 context_ref 依赖:

flutter pub add context_ref

初始化应用

确保你的应用被 ContextRef.root 包裹:

void main() {
  runApp(
    ContextRef.root(
      child: MaterialApp(
        home: MyApp(),
      ),
    ),
  );
}

(可选) 错误处理

为了在热重载时获得更好的错误信息,可以包裹默认的错误处理器:

void main() {
  ErrorWidget.builder = ContextRef.errorWidgetBuilder(ErrorWidget.builder);
  FlutterError.onError = ContextRef.onError(FlutterError.onError);
  runApp(
    ContextRef.root(
      child: MaterialApp(
        home: MyApp(),
      ),
    ),
  );
}

使用示例

示例1:初始化并传播值

下面是一个简单的例子,展示如何初始化并在子组件中访问值:

import 'package:flutter/material.dart';
import 'package:context_ref/context_ref.dart';

final _state = Ref<_State>();

class _State {
  String message = "Hello, World!";
}

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

  @override
  Widget build(BuildContext context) {
    // 创建并绑定状态到当前上下文
    _state.bind(context, () => _State());
    return const _Child();
  }
}

class _Child extends StatelessWidget {
  const _Child();

  @override
  Widget build(BuildContext context) {
    final state = _state.of(context);
    return Center(
      child: Text(state.message),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Context Ref Example')),
        body: const Example(),
      ),
    );
  }
}

示例2:提供已初始化的值

如果你已经有一个值,并希望将其传递给子组件,可以使用 bindValue 方法:

import 'package:flutter/material.dart';
import 'package:context_ref/context_ref.dart';

final _params = Ref<Params>();

class Params {
  final String paramValue;

  Params(this.paramValue);
}

class Example extends StatelessWidget {
  const Example({
    super.key,
    required this.params,
  });

  final Params params;

  @override
  Widget build(BuildContext context) {
    // 绑定已创建的值到当前上下文
    _params.bindValue(context, params);
    return const _Child();
  }
}

class _Child extends StatelessWidget {
  const _Child();

  @override
  Widget build(BuildContext context) {
    final params = _params.of(context);
    return Center(
      child: Text(params.paramValue),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Context Ref Example')),
        body: const Example(params: Params("Passed Param")),
      ),
    );
  }
}

通过这些示例,你可以看到 context_ref 插件是如何简化状态管理和上下文引用的。希望这对你有所帮助!


更多关于Flutter上下文引用插件context_ref的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter上下文引用插件context_ref的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,context_ref 是一个用于在 Dart 代码中安全地持有和引用 BuildContext 的插件。这对于在需要跨多个函数或类访问 BuildContext 时特别有用,比如在进行异步操作后更新UI时。

以下是一个简单的示例,演示了如何使用 context_ref 插件来持有和引用 BuildContext,并在异步操作后更新UI。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 context_ref 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  context_ref: ^0.1.6  # 请检查最新版本号

然后运行 flutter pub get 来获取依赖。

2. 使用 context_ref

下面是一个完整的示例,展示了如何使用 context_ref 来持有 BuildContext 并在异步操作后更新UI。

import 'package:flutter/material.dart';
import 'package:context_ref/context_ref.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Context Ref Example'),
        ),
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final ContextRef contextRef = ContextRef();

  void _fetchData() async {
    // 模拟异步操作
    await Future.delayed(Duration(seconds: 2));

    // 假设我们获取了一些数据
    String data = "Hello, Flutter!";

    // 使用 contextRef 来访问 BuildContext 并更新UI
    contextRef.currentContext?.run(() {
      // 你可以在这里更新状态
      // 例如,使用 setState 来触发UI更新
      setState(() {
        // 假设我们有一个变量来存储数据
        // _data = data; // 这里我们没有定义_data,所以只是示例
        // 但你可以根据实际情况更新状态
        ScaffoldMessenger.of(contextRef.currentContext!).showSnackBar(
          SnackBar(content: Text(data)),
        );
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    // 持有 BuildContext
    contextRef.hold(context);

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Press the button to fetch data'),
        ElevatedButton(
          onPressed: _fetchData,
          child: Text('Fetch Data'),
        ),
      ],
    );
  }

  @override
  void dispose() {
    // 释放 BuildContext
    contextRef.release();
    super.dispose();
  }
}

解释

  1. 依赖添加:在 pubspec.yaml 中添加了 context_ref 依赖。
  2. ContextRef 使用
    • _MyWidgetState 类中创建了一个 ContextRef 实例。
    • build 方法中,使用 contextRef.hold(context) 来持有当前的 BuildContext
    • _fetchData 异步方法中,使用 contextRef.currentContext?.run(() { ... }) 来访问 BuildContext 并更新UI。
    • dispose 方法中,调用 contextRef.release() 来释放 BuildContext

这个示例展示了如何在Flutter中使用 context_ref 插件来安全地持有和引用 BuildContext,以便在异步操作后更新UI。注意,在实际应用中,你应该根据具体需求来更新状态或执行其他UI操作。

回到顶部