Flutter插件kind的使用_一个用于创建描述数据类型的静态对象的 Dart 包

Flutter插件kind的使用

Introduction

这是 “package:kind”,一个用于创建描述数据类型的静态对象的 Dart 包。

该包受 Apache License 2.0 许可。

Links

Key features

  • 灵活

    • 该包会让你思考许多事情,例如:
      • 整数需要多少位?32位?52位?64位?
      • 列表的最大长度是多少?
      • 当你将 DateTime 实例转换为/从 JSON 时,你应该使用 UTC 还是本地时区?
    • 一旦你指定了你的数据模型,该包可以让你做以下事情:
      • JSON 序列化
      • 数据库对象映射
      • 自动实现 ==hashCodetoString()
      • 更多功能!
  • 无代码生成

    • 你需要手动编写 Kind<T> 规范(见下面的示例)。然而,AI 代码助手可以轻松自动化这一过程。
    • 该包也适用于任何类。你不需要修改这些类本身。例如,你可以序列化 Flutter SDK 小部件。

听起来很有趣吗?我们鼓励你比较这个框架与更成熟的包,如 json_serializable,并选择你最喜欢的一个。

Built-in kinds

Things you can do

Getting started

1. 添加依赖

在终端中,在你的项目目录下运行以下命令:

flutter pub add kind

如果不起作用,如果你的项目使用的是 Dart SDK 而不是 Flutter SDK,运行 dart pub add kind

2. 学习示例

查看下面的示例代码。

Examples

import 'package:kind/kind.dart';

void main() {
  //
  // 编码/解码 JSON 树:
  //
  final company = Company.kind.decodeJsonTree({
    'name': 'Flutter App Development Experts',
    'shareholders': [
      {
        '@type': 'Person',
        'firstName': 'Alice',
        'lastName': 'Smith',
      },
      {
        '@type': 'Person',
        'firstName': 'Bob',
      },
    ],
  });
  print("${company.name} has ${company.shareholders.length} shareholders.");

  //
  // 我们有 `==` 和 `hashCode` 因为我们扩展了 `HasKind`:
  //
  print(company.shareholders[1] == Person(firstName: 'Bob')); // --> true

  //
  // 我们有 `toString()` 因为我们扩展了 `HasKind`:
  //
  print(company.toString());
  // 打印:
  //   Company(
  //     "Flutter App Development Experts",
  //     shareholders: [
  //       Person(
  //         firstName: 'John',
  //         lastName: 'Doe',
  //       ),
  //       Person(firstName: 'Bob'),
  //     ],
  //   )
}

//
// 示例类 #1:
//   "一个静态的 `_walk` 函数"
//
class Company extends Shareholder {
  static const kind = ImmutableKind<Company>(
    name: 'Company',
    blank: Company(''),
    walk: _walk,
  );

  [@override](/user/override)
  final String name;

  final List<Shareholder> shareholders;

  const Company(this.name, {this.shareholders = const []});

  [@override](/user/override)
  Kind<Company> get runtimeKind => kind;

  static Company _walk(Mapper f, Company t) {
    final name = f.positional(t.name, 'name');
    final shareholders = f(
      t.shareholders,
      'shareholders',
      kind: const ListKind(
        elementKind: Shareholder.kind,
      ),
    );

    // 下面是一个我们推荐的性能优化:
    if (f.canReturnSame) {
      return t;
    }

    // 最后,构建一个新的实例:
    return Company(
      name,
      shareholders: shareholders,
    );
  }
}

//
// 示例 #2:
//   "一个扩展 `Walkable` 的类"
//
class Person extends Shareholder with Walkable {
  static const kind = ImmutableKind<Person>.walkable(
    name: 'Person',
    blank: Person(firstName: ''),
  );

  /// 名字
  final String firstName;

  /// 姓氏
  final String lastName;

  const Person({
    required this.firstName,
    this.lastName = '',
  });

  [@override](/user/override)
  String get name => '$firstName $lastName';

  [@override](/user/override)
  Kind<Person> get runtimeKind => kind;

  [@override](/user/override)
  Person walk(Mapper f) {
    final firstName = f.required(
      this.firstName,
      'firstName',
      kind: const StringKind.singleLineShort(),
    );
    final lastName = f(
      this.lastName,
      'lastName',
      kind: const StringKind.singleLineShort(),
    );
    if (f.canReturnSame) {
      return this;
    }
    return Person(
      firstName: firstName,
      lastName: lastName,
    );
  }
}

//
// 示例 #3:
//   "一个多态类"
//
abstract class Shareholder extends HasKind {
  static const kind = PolymorphicKind<Shareholder>.sealed(
    defaultKinds: [
      Person.kind,
      Company.kind,
    ],
  );

  const Shareholder();

  String get name;
}

更多关于Flutter插件kind的使用_一个用于创建描述数据类型的静态对象的 Dart 包的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter插件kind的使用_一个用于创建描述数据类型的静态对象的 Dart 包的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,尽管kind这个Flutter插件的具体功能和用途是未定义的,但我们可以基于插件名称和一些常见的Flutter插件开发模式,来推测并展示一个可能的插件使用案例。在这个案例中,我们将假设kind插件是用来处理某种类型数据(比如用户信息、配置信息等)的,并提供了一些基础操作如获取、设置和删除等。

首先,我们需要定义插件的接口和方法。由于Flutter插件通常使用Dart和原生代码(如Kotlin/Java for Android, Swift/Objective-C for iOS)进行交互,这里我们只展示Dart端的代码,并假设原生端的实现已经存在。

1. 定义插件接口

在Dart中,我们通常会为插件定义一个接口(或抽象类),以便在应用程序中统一使用。

// kind_plugin.dart
import 'dart:typed_data';
import 'package:flutter/services.dart';

abstract class KindPlugin {
  static const MethodChannel _channel = MethodChannel('com.example.kind_plugin');

  static Future<Map<String, dynamic>> getData(String key) async {
    final Map<String, dynamic> result = await _channel.invokeMethod('getData', key);
    return result;
  }

  static Future<void> setData(String key, Map<String, dynamic> value) async {
    await _channel.invokeMethod('setData', {'key': key, 'value': value});
  }

  static Future<void> deleteData(String key) async {
    await _channel.invokeMethod('deleteData', key);
  }
}

2. 使用插件

接下来,我们可以在Flutter应用程序中使用这个插件。以下是一个简单的使用示例:

// main.dart
import 'package:flutter/material.dart';
import 'kind_plugin.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Kind Plugin Example'),
        ),
        body: KindPluginExample(),
      ),
    );
  }
}

class KindPluginExample extends StatefulWidget {
  @override
  _KindPluginExampleState createState() => _KindPluginExampleState();
}

class _KindPluginExampleState extends State<KindPluginExample> {
  String _dataResult = '';

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: <Widget>[
          Text('Kind Plugin Data Result:'),
          Text(_dataResult),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _fetchData,
            child: Text('Fetch Data'),
          ),
          SizedBox(height: 10),
          ElevatedButton(
            onPressed: _saveData,
            child: Text('Save Data'),
          ),
          SizedBox(height: 10),
          ElevatedButton(
            onPressed: _deleteData,
            child: Text('Delete Data'),
          ),
        ],
      ),
    );
  }

  Future<void> _fetchData() async {
    try {
      final data = await KindPlugin.getData('example_key');
      setState(() {
        _dataResult = data.toString();
      });
    } catch (e) {
      setState(() {
        _dataResult = 'Error fetching data: $e';
      });
    }
  }

  Future<void> _saveData() async {
    try {
      await KindPlugin.setData('example_key', {'name': 'John Doe', 'age': 30});
      setState(() {
        _dataResult = 'Data saved successfully!';
      });
    } catch (e) {
      setState(() {
        _dataResult = 'Error saving data: $e';
      });
    }
  }

  Future<void> _deleteData() async {
    try {
      await KindPlugin.deleteData('example_key');
      setState(() {
        _dataResult = 'Data deleted successfully!';
      });
    } catch (e) {
      setState(() {
        _dataResult = 'Error deleting data: $e';
      });
    }
  }
}

3. 原生端实现(假设)

虽然我们不能在这里提供完整的原生端实现,但我们可以概述一下原生端需要做的事情。

  • Android: 在MainActivity.ktMainActivity.java中注册插件,并实现MethodChannel的回调方法getDatasetDatadeleteData
  • iOS: 在AppDelegate.swiftAppDelegate.m中注册插件,并在相应的类中实现MethodChannel的回调方法。

这些回调方法将处理数据的获取、设置和删除操作,可能是通过访问文件系统、数据库或其他存储机制来实现的。

请注意,这个示例是基于对kind插件功能的合理推测,实际使用时需要根据插件的官方文档和API进行具体实现。

回到顶部