Flutter通信插件wire_flutter的使用

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

Flutter通信插件wire_flutter的使用

WireDataBuilder Widget - wire_flutter

WireDataBuilderwire_flutter 工具包中的一个数据容器层。

如何使用

该组件订阅数据变化,并在变化发生时重新构建小部件。当调用 Wire.data('param', value) 更新数据时,WireDataBuilder 小部件会重建。

示例代码

WireDataBuilder<int>(
  dataKey: CounterDataKey.COUNT,
  builder: (context, value) => Text(
    '$value',
    style: Theme.of(context).textTheme.headline4,
  )
)

你可以从用户界面发送消息或信号,这些消息或信号可以在应用程序的任何其他地方被监听,完全与用户界面解耦:

FloatingActionButton(
  onPressed: () => Wire.send(CounterSignal.INCREASE),
  child: Icon(Icons.add),
)

可以通过信号来响应并更新数据(甚至传递函数作为数据值)。新的值或函数调用的结果将传播到 WireData 监听器,并在 WireDataBuilder 中重建小部件以使用新的值。

Wire.add(this, CounterSignal.INCREASE, (payload, wireId) {
  Wire.data(CounterParams.COUNT, (value) {
    return (value ?? 0) + 1;
  });
});

TodoMVC 示例

示例展示

示例代码

创建列表,参数为 TodoDataKeys.LIST,这是一个存储在 Wire.data 中的 TodoVO 对象的 ID 列表。

WireDataBuilder<List<String>>(
  dataKey: TodoDataKeys.LIST,
  builder: (context, list) => ListView.builder(
    key: ArchSampleKeys.todoList,
    itemCount: list.length,
    itemBuilder: (BuildContext context, int index) {
      final todoId = list[index];
    ...

TodoItem 消费此 ID(字符串),并检索/订阅 WireData 以便在发生变化时进行更新——这是如何将 TodoVO 的更改反映到用户界面的方式。

Widget build(BuildContext context) {
  return WireDataBuilder<TodoVO>(
    dataKey: id,
    builder: (context, todoVO) => Visibility(
      visible: todoVO.visible, // 渲染来自 TodoVO 的值
      child: ListTile(
        onTap: onTap,
        leading: Checkbox(
          key: ArchSampleKeys.todoItemCheckbox(todoVO.id),
          value: todoVO.completed, // 渲染来自 TodoVO 的值
          onChanged: onToggle,
        ),
    ...

任何更改都被“转换”为信号并发送给其监听器:

FilterButton(
  isActive: activeTab == AppTab.todos,
  activeFilter: TodoFilterValue.ALL,
  onSelected: (filter) => Wire.send(TodoViewSignal.FILTER, filter),
)

视图不知道谁将在哪里处理这些信号,它只关心在变化时渲染数据。

Wire.add(this, TodoViewSignal.INPUT,  _signalProcessor);
Wire.add(this, TodoViewSignal.EDIT,   _signalProcessor);
Wire.add(this, TodoViewSignal.DELETE, _signalProcessor);
Wire.add(this, TodoViewSignal.TOGGLE, _signalProcessor);
Wire.add(this, TodoViewSignal.FILTER, _signalProcessor);
Wire.add(this, TodoViewSignal.CLEAR_COMPLETED, _signalProcessor);
Wire.add(this, TodoViewSignal.COMPLETE_ALL, _signalProcessor);

信号可以在任何地方处理,甚至在不相关的多个地方——在这个例子中,它是一个控制器——TodoController

你可能会认为 TodoController 是 Redux 中的 reducer,它监听“事件”-信号并设置数据。在这个例子中,控制器是应用程序的大脑,它具有业务决策逻辑,并知道如何处理数据并将它们发送到何处进行进一步存储——TodoModel。因此,它可以自行存储数据,但我们更倾向于解耦职责,让控制器仅仅将数据委托给模型,模型知道如何以及在哪里存储数据并在更新前将其写入 Wire.data

void _signalProcessor(payload, wireId) {
  final wire = Wire.get(wireId: wireId).single;
  print('> TodoProcessor -> ${wire.signal}: data = ' + data.toString());
  switch (wire.signal) {
    case TodoViewSignal.INPUT:
      var createDTO = payload as CreateDTO;
      var text = createDTO.text;
      var note = createDTO.note;
      var completed = createDTO.completed;
      if (text != null && text.isNotEmpty) {
        todoModel.create(text, note, completed);
        Wire.send(TodoViewSignal.CLEAR_INPUT); // 控制器向系统的其他部分发送信号
      }
      break;
    case TodoViewSignal.EDIT:
      var editTodoDTO = payload as EditDTO;
      var todoText = editTodoDTO.text;
      var todoNote = editTodoDTO.note;
      var todoId = editTodoDTO.id;
      if (todoText.isEmpty) {
        todoModel.remove(todoId);
      } else {
        todoModel.update(todoId, todoText, todoNote);
      }
      break;
 ...

视图也可以订阅 Wire 信号 (Wire.add) 并在来自系统其他部分(控制器/模型或其他视图)的信号时更新自身,而无需知道是谁请求的。

示例见 Wire 存储库中的 TodoMVC 示例:

class TodoInputView extends DomElement {
  TodoInputView(InputElement dom):super(dom) {
    Wire.add(this, TodoViewSignal.CLEAR_INPUT, (s, d) => dom.value = '');
    dom
      ..text = ''
      ..onKeyPress.listen((e) =>
        e.keyCode == KeyCode.ENTER &&
          Wire.send(TodoViewSignal.INPUT, CreateDTO(dom.value, '')));
  }
}

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

1 回复

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


当然,以下是一个关于如何使用Flutter通信插件wire_flutter的代码案例。这个案例将展示如何在Flutter应用中集成并使用wire_flutter插件进行通信。

首先,确保你已经在pubspec.yaml文件中添加了wire_flutter插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  wire_flutter: ^最新版本号  # 请替换为实际的最新版本号

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

接下来,我们需要在Flutter应用中初始化并使用wire_flutter插件。以下是一个简单的示例,展示了如何使用该插件进行基本的通信操作。

1. 初始化插件

在你的Flutter项目的main.dart文件中,首先导入必要的包并初始化插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Wire Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  WireClient? wireClient;

  @override
  void initState() {
    super.initState();
    // 初始化WireClient,替换为你的API Key和Room ID
    String apiKey = "你的API_KEY";
    String roomId = "你的ROOM_ID";
    wireClient = WireClient(apiKey: apiKey, roomId: roomId);

    // 监听连接状态变化
    wireClient!.onConnectionStateChanged = (state) {
      print("Connection state changed: $state");
    };

    // 监听消息接收
    wireClient!.onMessageReceived = (message) {
      print("Message received: ${message.content}");
    };

    // 连接到Wire房间
    wireClient!.connect();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Wire Flutter Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '发送消息到Wire房间',
            ),
            SizedBox(height: 20),
            TextField(
              decoration: InputDecoration(hintText: '输入消息'),
              onSubmitted: (message) {
                if (wireClient != null && wireClient!.isConnected) {
                  wireClient!.sendMessage(message);
                } else {
                  print("客户端未连接");
                }
              },
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 断开连接并释放资源
    wireClient?.disconnect();
    super.dispose();
  }
}

2. 配置插件权限

根据你的应用需求,你可能需要在AndroidManifest.xmlInfo.plist文件中配置必要的权限,例如网络权限。

Android

AndroidManifest.xml中添加网络权限:

<uses-permission android:name="android.permission.INTERNET"/>

iOS

Info.plist中添加网络权限描述(如果需要):

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

注意事项

  1. API Key 和 Room ID:你需要替换代码中的你的API_KEY你的ROOM_ID为实际的Wire API Key和Room ID。
  2. 错误处理:为了简化示例,这里省略了错误处理逻辑。在实际应用中,你应该添加适当的错误处理,例如处理连接失败、消息发送失败等情况。
  3. UI 更新:在接收到消息时,你可能需要更新UI来显示新消息。这可以通过使用setState方法来实现。

通过上述代码示例,你应该能够在Flutter应用中集成并使用wire_flutter插件进行基本的通信操作。希望这对你有所帮助!

回到顶部