『Flutter-插件篇』实现一款超酷的动态天气背景插件

  |     |   本文总阅读量:

前言

前不久,利用周末时间学习并完成一个简单的 Flutter 项目 - 简悦天气简约不简单,丰富不复杂,这是一款简约风格的 flutter 天气项目,提供实时、多日、24 小时、台风路径、语音播报以及生活指数等服务,支持定位、删除、搜索等操作。

下图为主页效果,点击下载 进行体验:

home

之前发了三篇文章:

对天气背景动画的具体实现做了详情的分析和总结,很多小伙伴私信我,希望可以出一个天气动态背景插件。正好当时写的时候,就以模块化的思想,单一和解耦的设计原则,放置在单独的 package 下,所以后续根据官方编写插件文档,抽成插件,希望给有需要的小伙伴能提供帮助。同时,分享如何写一个高质量插件的过程和注意事项。

因此,本篇文章的主要两个主题:

  1. 介绍 flutter_weather_bg 此插件的功能和使用说明
  2. 分享编写插件的方法和注意事项

超酷的动态天气背景插件

介绍

pub 地址

Github 地址

这是一款丰富炫酷的天气动态背景插件,支持 15 种天气类型。

功能

  • 支持 15 种 天气类型:晴、晴晚、多云、多云晚、阴、小中大雨、小中大雪、雾、霾、浮尘和雷暴
  • 支持 动态缩放尺寸,适配多场景下展示
  • 支持 切换天气类型时过度动画

支持的平台

  • Flutter Android
  • Flutter iOS
  • Flutter web
  • Flutter desktop

安装

添加 flutter_weather_bg: ^2.8.2pubspec.yaml 文件中,并且导包:

1
import 'package:flutter_weather_bg/flutter_weather_bg.dart';

使用

通过创建 WeatherBg 配置天气类型,需要传入宽高来完成最终展示

1
WeatherBg(weatherType: _weatherType,width: _width,height: _height,)

截图效果

对不同的特点进行相应的 gif 展示。

  1. 全屏沉浸式翻页效果

home

  1. 城市管理列表效果

list

  1. 多样的宫格效果

grid

  1. 切换天气类型时的过度动画效果

check

  1. 修改宽高的适配效果

width_height

编写一款高质量的插件

目前 Flutter 那么火,离不开高热度的社区以及丰富的插件,所以如果有想法或者有能力的话,尽可能的为社区贡献出一份微薄之力吧。

那既然选择编写并发布一款插件,就要对其负责,不只是负责完成编码任务,尽可能的提供详细的使用文档说明,有条件的话,以图文并茂的方式更好,这样开发者才会愿意使用你的插件。

创建插件项目

使用 Android Studio 可以直接创建 Flutter Plugin,或者直接通过命令 flutter create -t plugin flutter_demo_plugin 直接在当前文件夹生成插件目录。

创建好后,会生成如下的文件目录:

目录 描述
android/ android 端相关代码
ios/ ios 相关代码
example/ 样例演示项目
lib/ flutter 端代码
test/ 单元测试代码
CHANGELOG 每个版本的更新日志说明
LICENSE license 相关
pubspec.yaml 项目名称、项目描述、版本、依赖等相关
README.md 项目的 readme 文档

编写插件逻辑

Android 端

android/src/main/java/com/example/flutter_demo_plugin/FlutterDemoPlugin.java 中编写与 Android 端交互的逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class FlutterDemoPlugin implements FlutterPlugin, MethodCallHandler {

private MethodChannel channel;

@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_demo_plugin");
channel.setMethodCallHandler(this);
}

public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_demo_plugin");
channel.setMethodCallHandler(new FlutterDemoPlugin());
}

@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}

@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
}
  1. 创建 MethodChannel,定义通信的唯一标识 flutter_demo_plugin
  2. 注册
  3. 根据方法来处理相应的逻辑

iOS 端

iOS 类似,只不过是按照 iOS 端的写法。

  1. 创建 FlutterDemoPlugin.h
1
2
3
4
#import <Flutter/Flutter.h>

@interface FlutterDemoPlugin : NSObject<FlutterPlugin>
@end
  1. FlutterDemoPlugin.m 中编写逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#import "FlutterDemoPlugin.h"

@implementation FlutterDemoPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"flutter_demo_plugin"
binaryMessenger:[registrar messenger]];
FlutterDemoPlugin* instance = [[FlutterDemoPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"getPlatformVersion" isEqualToString:call.method]) {
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
} else {
result(FlutterMethodNotImplemented);
}
}

@end

Flutter 端

直接在 lib/flutter_demo_plugin.dart 中调用定义好的方法即可:

1
2
3
4
5
6
7
8
9
class FlutterDemoPlugin {
static const MethodChannel _channel =
const MethodChannel('flutter_demo_plugin');

static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
}

发布前准备

代码逻辑编写完毕,离发布还有最后一步,也是编写高质量插件的重要一步。

在项目发布后,等待一段时间,这里会有对项目的评价分数,开发者可以据此作为选择的标准。那如何达到此标准,接下来会进行介绍。

  1. 在 pubspec.yaml 中配置版本信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 配置项目名称
name: flutter_demo_plugin
// 配置项目描述,简要并能概括项目的内容和特点
description: A new Flutter plugin.
// 项目版本,每次发布更新,都需要增加此配置
version: 0.0.1
// 作者信息
author:
// 主页信息
homepage:

environment:
sdk: ">=2.7.0 <3.0.0"
flutter: ">=1.20.0 <2.0.0"

dependencies:
flutter:
sdk: flutter

dev_dependencies:
flutter_test:
sdk: flutter

// 如果只是纯 dart 插件,此断可以不加
flutter:
plugin:
platforms:
android:
package: com.example.flutter_demo_plugin
pluginClass: FlutterDemoPlugin
ios:
pluginClass: FlutterDemoPlugin
macos:
pluginClass: FlutterDemoPlugin
web:
pluginClass: FlutterDemoPlugin
fileName: flutter_demo_plugin.dart
  1. 提供详细的 README.md 项目使用介绍,最好是英文

  2. 提供详细的 CHANGELOG.md 版本迭代更新日志

  3. example/lib/main.dart 中,要有详细的代码使用案例

  4. 代码中,对公有方法和变量,提供尽可能详细的说明

  5. 完善插件支持平台

  6. 代码保证完整性、正确性和可编译

  7. 插件包中的所有依赖要保证是最新版本

这些是通过脚本工具自动检测,除此静态的配置,更重要的代码质量和尽可能的去维护,这样才是一款合格的插件。

发布

最后,只需要通过 flutter packages pub publish --server=https://pub.dartlang.org 命令即可发布。

当看到:

恭喜证明你上传成功了

#rewardButton { background-color: #ea6f5a; } .btn-pay { margin-bottom: 20px; padding: 8px 25px; font-size: 16px; color: #fff; background-color: #ea6f5a; } .btn { display: inline-block; margin-bottom: 0; font-weight: 400; text-align: center; vertical-align: middle; touch-action: manipulation; cursor: pointer; background-image: none; border: 1px solid transparent; white-space: nowrap; padding: 6px 12px; font-size: 14px; line-height: 1.42857; border-radius: 4px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #QR img{ height: 200px; height: 200px; margin: 20px; }
文章目录
  1. 1. 前言
  2. 2. 超酷的动态天气背景插件
    1. 2.1. 介绍
    2. 2.2. 功能
    3. 2.3. 支持的平台
    4. 2.4. 安装
    5. 2.5. 使用
    6. 2.6. 截图效果
  3. 3. 编写一款高质量的插件
    1. 3.1. 创建插件项目
    2. 3.2. 编写插件逻辑
      1. 3.2.1. Android 端
      2. 3.2.2. iOS 端
      3. 3.2.3. Flutter 端
    3. 3.3. 发布前准备
    4. 3.4. 发布
您是第 位小伙伴 | 本站总访问量 | 已经写了 120.4k 字啦

载入天数...载入时分秒...