# 示例插件

第一次开发时，从 Hello 开始。之后可以按下面的顺序增加参数、状态和页面。每个项目都有 `manifest.json` 和操作说明，代码插件另有可运行入口，下载后可通过“加载开发文件夹”运行。

| 项目 | 你会用到的功能 | 下载 |
| --- | --- | --- |
| Hello | 动作参数和步骤结果 | [源码](/docs-assets/examples/hello.zip) · [安装包](/docs-assets/examples/example.hello-1.0.0.flyext) |
| 文本处理 | 文本输入、列表和数字输出 | [源码](/docs-assets/examples/text-toolkit.zip) · [安装包](/docs-assets/examples/example.text-toolkit-1.0.0.flyext) |
| 状态按钮 | 枚举状态和按钮外观切换 | [源码](/docs-assets/examples/state-button.zip) · [安装包](/docs-assets/examples/example.state-button-1.0.0.flyext) |
| 计数器 | 独立实例、页面交互和配置 | [源码](/docs-assets/examples/counter.zip) · [安装包](/docs-assets/examples/example.counter-1.0.0.flyext) |
| 插件全局设置 | 自定义配置页、宿主保存与私密字段 | [源码](/docs-assets/examples/plugin-settings.zip) · [安装包](/docs-assets/examples/example.plugin-settings-1.0.0.flyext) |
| 网络组件 | 一次性数据请求和后台联网 | [源码](/docs-assets/examples/network-card.zip) · [安装包](/docs-assets/examples/example.network-card-1.0.0.flyext) |
| 服务提供方 | 发布一个求和服务 | [源码](/docs-assets/examples/service-provider.zip) · [安装包](/docs-assets/examples/example.service-provider-1.0.0.flyext) |
| 极简天气 | 复用天气服务并提供独立界面 | [源码](/docs-assets/examples/weather-card.zip) · [安装包](/docs-assets/examples/example.weather-card-1.0.0.flyext) |
| 静态图标包 | 无后台的图标资源贡献 | [源码](/docs-assets/examples/icon-pack.zip) · [安装包](/docs-assets/examples/example.icon-pack-1.0.0.flyext) |
| 服务消费方 | 调用求和服务 | [源码](/docs-assets/examples/service-consumer.zip) · [安装包](/docs-assets/examples/example.service-consumer-1.0.0.flyext) |

## 运行计数器

加载计数器后，在设备编辑器中放置两份。点击第一份，第二份的计数应该保持不变。再修改其中一份的步长，下一次点击应使用新的步长。这可以帮助你理解实例状态与实例配置的区别。

## 运行服务示例

先加载并启动提供方，再加载消费方。在流程中执行消费方的求和动作，输入 `[1, 2, 3]`，结果应为 `6`。停止提供方后再次执行，可以看到消费方如何处理服务不可用的情况。

## 修改项目

这些项目使用 `example.*` ID。为你的插件发布新包时，替换为自己的 ID；服务示例还需要同时修改消费方的 `dependencies`、`uses` 和代码中的目标插件 ID。

## 天气界面：复用其他插件的后台

`weather-card` 是独立界面示例。先启用 `builtin.weather` 1.2.0，再关联或安装示例，在超级块目录中添加“极简天气”。它声明 dependencies 与 uses，城市选项和天气均来自公共服务，本身不请求网络权限。



```json
{
  "apiVersion": 1,
  "id": "example.weather-card",
  "name": "极简天气（复用服务）",
  "version": "1.0.0",
  "description": "只定义界面，通过天气插件获取数据和城市选项",
  "hostPlatforms": [
    "windows",
    "macos",
    "linux",
    "harmonyos"
  ],
  "main": "index.js",
  "permissions": [],
  "dependencies": {
    "builtin.weather": "^1.2.0"
  },
  "uses": [
    {
      "pluginId": "builtin.weather",
      "serviceId": "forecast",
      "version": 1
    }
  ],
  "contributes": {
    "widgets": [
      {
        "id": "card",
        "title": "极简天气",
        "page": "pages/card/index.html",
        "defaultSize": {
          "cols": 2,
          "rows": 1
        },
        "settingsSchema": {
          "properties": {
            "city": {
              "type": "string",
              "title": "城市",
              "control": "search-select",
              "dynamicOptions": true,
              "default": "cn:beijing",
              "titleKey": "widgets.card.settingsSchema.properties.city.title"
            }
          }
        },
        "titleKey": "widgets.card.title"
      }
    ],
    "dataProviders": [
      {
        "id": "forecast",
        "widget": "card",
        "lifetime": "request",
        "visibility": "instance",
        "responseSchema": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string"
            },
            "source": {
              "type": "string"
            },
            "temperature": {
              "type": "number"
            },
            "description": {
              "type": "string"
            },
            "icon": {
              "type": "string"
            },
            "hourly": {
              "type": "array",
              "items": {
                "type": "object"
              },
              "maxItems": 6
            },
            "daily": {
              "type": "array",
              "items": {
                "type": "object"
              },
              "maxItems": 5
            }
          },
          "required": [
            "city",
            "source",
            "temperature",
            "description",
            "icon",
            "hourly",
            "daily"
          ]
        },
        "maxBytes": 16384
      }
    ]
  },
  "i18n": {
    "defaultLocale": "zh-CN",
    "resources": {
      "zh-CN": "locales/zh-CN.json",
      "en-US": "locales/en-US.json"
    }
  },
  "nameKey": "plugin.name",
  "descriptionKey": "plugin.description"
}
```





```js
"use strict";
const { definePlugin } = require(process.env.FLYONDECK_SDK_PATH);
const call = (context, method, args) => context.plugins.call("builtin.weather", "forecast", method, args);
definePlugin({
  widgetOptions: { card: { city: (request, context) => call(context, "searchCities", request) } },
  dataProviders: { forecast: ({ settings }, context) => call(context, "getForecast", { city: settings.city }) }
});
```



## 静态图标包

`icon-pack` 只提供 Studio 单色图标，不包含后台入口。安装并启用后，在按钮外观或图标设置中搜索“播放”或“暂停”。停止后台不影响静态资源；禁用图标包会将其从可选目录移除。



```json
{
  "apiVersion": 1,
  "id": "example.icon-pack",
  "name": "示例图标包",
  "nameKey": "plugin.name",
  "version": "1.0.0",
  "hostPlatforms": [
    "windows",
    "macos",
    "linux",
    "harmonyos"
  ],
  "permissions": [],
  "hostCapabilities": {
    "required": {
      "icons.library": 1
    }
  },
  "i18n": {
    "defaultLocale": "zh-CN",
    "resources": {
      "zh-CN": "locales/zh-CN.json",
      "en-US": "locales/en-US.json"
    }
  },
  "contributes": {
    "iconPacks": [
      {
        "id": "studio",
        "title": "Studio 单色图标",
        "titleKey": "packs.studio.title",
        "paint": "monochrome",
        "index": "icons/index.json",
        "license": "CC0-1.0"
      }
    ]
  }
}
```





```json
{
  "schemaVersion": 1,
  "icons": [
    {
      "id": "play",
      "title": "播放",
      "titleKey": "icons.play.title",
      "keywords": [
        "play",
        "播放",
        "开始"
      ],
      "file": "icons/play.svg"
    },
    {
      "id": "pause",
      "title": "暂停",
      "titleKey": "icons.pause.title",
      "keywords": [
        "pause",
        "暂停"
      ],
      "file": "icons/pause.svg"
    }
  ]
}
```


