两行扩展方法搞定颜色明暗调节:Color.darken / Color.lighten 纯 Dart 纯计算,鸿蒙零权限即取即用 —— color_brightness 鸿蒙使用指南

为什么需要颜色明暗调节?

按压态比主色深一档、hover 态浅一档、禁用态再淡一层、卡片背景由主题色派生……这些场景都绕不开一个问题:给一个 Color,怎么按百分比变暗 / 变亮? 手撸 HSL 换算又长又容易错,而 color_brightness 给 Color 挂了两个扩展方法——darken(percent) 与 lighten(percent),一行搞定。

这个库还有个特别之处:它是纯 Dart 库,明暗运算完全不经过方法通道;鸿蒙适配的实质工作是补齐插件工程形态(ohos 平台声明 + ArkTS 注册类),让鸿蒙与其余五个平台形态完全一致。本文基于其鸿蒙适配版,介绍在 OpenHarmony 上的接入与实测。

开发工具:华为云码道(DevEco Studio)

配套仓库:原库 kakzaki/flutter_color_brightness(pub 包名 color_brightness,版本 1.0.0),鸿蒙适配版 https://atomgit.com/oh-flutter/flutter_color_brightness(TAG:1.0.0-ohos-1.0.0-beta.1,分支 main)

在这里插入图片描述


一、最终运行效果

示例 App 是一个覆盖面很全的演示页,首屏展示插件说明与基础用法:

请添加图片描述

  • 插件说明卡片:两个接口的签名与约束说明——Color.darken([double percent = 10])、Color.lighten([double percent = 10]),percent 取值 1~100,只改写 RGB、alpha 原样保留;
  • 基础用法卡片:Colors.red(#FFF44336)固定 50% 对照——darken(50) 得 #FF7A221B、lighten(50) 得 #FFFAA19B;
  • 默认参数卡片:darken() 与 darken(10) 结果完全一致(#FF3949A3),证明省略参数时按 10 计算。

往下滑是交互区与结果区:

请添加图片描述

  • 交互调节卡片:六个基色 ChoiceChip(红橙绿青蓝紫)+ 1~100 滑块 + 1/10/25/50/75/90/100 快捷比例按钮(含两个边界值);
  • 自定义基色卡片:R/G/B 三个通道滑块构造任意 Color(当前 214/96/77,亮度 0.235),证明接口不限于预设色;
  • 实时结果卡片:原色 / darken(50) / lighten(50) 三块并列,各带相对亮度值(0.235 → 0.054 / 0.482)。

再往下是"透明度保持"与派生色阶:

请添加图片描述

  • 透明度保持卡片:棋盘格底上展示半透明基色变换后 alpha 不变;
  • 明暗渐变卡片:从 darken(100)(纯黑)经原色连续过渡到 lighten(100)(纯白)的渐变带;
  • 色阶调色板卡片:以基色为锚点向两侧派生的色阶,与主色保持同一色相。

页尾是主题派生实战:

请添加图片描述

  • 明暗主题预览:用 lighten(85) / darken(85) 派生亮色面与暗色面,并按各自亮度挑选可读前景色——"同源配色"的现成范式;
  • 当前调用片段:随基色与比例实时生成可复制的代码片段。

验证点结果一览:

验证点结果
插件注册(Adding plugin: ColorBrightnessPlugin)✅ 通过
通道注册 color_brightness✅ 通过
darken(50) 数值正确(#F44336 → #7A221B,逐通道核算)✅ 通过
lighten(50) 数值正确(#F44336 → #FAA19B,逐通道核算)✅ 通过
默认参数(省略 percent = 10)✅ 通过
透明度保持(alpha 不参与运算)✅ 通过
自定义任意 Color 生效✅ 通过
全程无需申请任何敏感权限✅ 通过

鸿蒙技术点:FlutterPage 与 XComponent 渲染管线

与所有 Flutter 鸿蒙化工程一致:Index.ets 的 @Entry 组件在 build() 中使用 FlutterPage(内部封装 XComponent 渲染画布,经 NAPI 桥接 C++ 引擎层);EntryAbility 继承 FlutterAbility,在 configureFlutterEngine 中 GeneratedPluginRegistrant.registerWith(flutterEngine) 完成插件注册——ColorBrightnessPlugin 由此挂进引擎。

以下是操作的视屏,可以参考一下:

Example 启动授权 Example 启动授权 Example 启动授权 Example 启动授权


二、color_brightness 是什么

原库(pub 包 color_brightness,作者 kakzaki)只做一件事:给 Color 扩展两个明暗调节方法。整个 lib/ 不到 20 行核心代码:

extension ColorBrightness on Color {
  Color darken([double percent = 10]) { ... }   // 按百分比变暗
  Color lighten([double percent = 10]) { ... }  // 按百分比变亮
}

使用者友好特点(分条):

  • 极小面:两个扩展方法,无状态、无依赖(仅 Flutter SDK),学习成本为零;
  • 纯 Dart 计算:ARGB 数值运算,无平台通道调用,各平台结果逐位一致;
  • alpha 安全:只改写 RGB 通道,透明度原样保留;
  • 入参有护栏:assert(1 <= percent && percent <= 100),越界在调试期立刻暴露;
  • 鸿蒙零权限:明暗运算在 Dart 层完成,原生侧只有一个 getPlatformVersion 模板桩,无需申请任何权限。

接口说明

ColorBrightness 扩展(对象为 Color):

方法入参返回说明
darkendouble percent(1~100,默认 10)Color每个通道乘以 1 - percent/100,alpha 不变
lightendouble percent(1~100,默认 10)Color每个通道向 255 线性插值 percent/100,alpha 不变

ColorBrightnessPlugin(原生桩):

方法返回说明
getPlatformVersionFuture<String>「平台 + 系统版本」字符串;Dart 层无调用方(上游设计如此),仅作通道自检用

各平台通道契约对照

平台通道名方法名返回值示例实现语言
Androidcolor_brightnessgetPlatformVersionAndroid 12Kotlin
iOS / macOScolor_brightnessgetPlatformVersioniOS 18.0Swift
Windowscolor_brightnessgetPlatformVersionWindows 10+C++
Linuxcolor_brightnessgetPlatformVersionLinux <uname>C
OHOS(本次新增)color_brightnessgetPlatformVersionHarmonyOS 6.1.0.145ArkTS

说明:适配时全量检索过 Dart 层——MethodChannel / Platform.is* 命中数均为 0,即库的公开能力完全由 Dart 实现,六个平台的原生代码对功能没有任何贡献。鸿蒙侧保留 getPlatformVersion 只为与其余平台形态一致。


三、环境准备

本文实测环境:

环境项版本
Flutter(ohos 版)3.47.7-ohos-1.0.0(channel oh-3.47-dev,Dart 3.13.3)
DevEco Studio26.0.0(本机 SDK API 26)
编译 SDK6.1.1(24)(compatibleSdkVersion / targetSdkVersion)
真机华为 TLR-AL00,HarmonyOS 6.1.0.145(C00E120R3P5),API 24

鸿蒙技术点:compatibleSdkVersion 要按设备的 版本(API) 形式写

模板生成的是 compatibleSdkVersion: "26.0.0"(沿用本机 SDK 版本),部署到 API 24 设备时报"应用的 compatibleSdkVersion 和 releaseType 与设备不匹配"。正确做法是查 DevEco 的版本映射表(hvigor-ohos-plugin/.../hos-config.json 的 osVersionMapper):6.1.1 → 24,并且 API < 26 必须写成 版本(API) 格式:

"compatibleSdkVersion": "6.1.1(24)",
"targetSdkVersion": "6.1.1(24)",

修复后产物 pack.info 的 apiVersion 变为 {compatible: 24, releaseType: "Release", target: 24},与设备完全一致。本机只装了 API 26 的 SDK 也不影响——compatibleSdkVersion 声明的是最低兼容版本,编译仍用已安装的 SDK。

两点提醒:

  1. 需要 ohos 版 Flutter SDK(本文使用 3.47.7-ohos-1.0.0);
  2. Windows 命令行下 flutter build hap 可能触发 DevEco ohpm.bat 的批处理递归缺陷(宿主环境已知问题,与插件无关),可改用 hvigorw assembleHap 直调打包。

四、引入依赖

在工程 pubspec.yaml 中添加 git 依赖:

...

dependencies:
  color_brightness:
    git:
      url: https://atomgit.com/oh-flutter/flutter_color_brightness
      # ref: 1.0.0-ohos-1.0.0-beta.1
      ref: TAG  # 请根据下方TAG版本对应表选择TAG
...

执行命令:

flutter pub get

TAG 版本对应表

Flutter 框架版本TAG分支
3.471.0.0-ohos-1.0.0-beta.1main

TAG 命名规则:原库版本-ohos-版本号。原库 1.0.0 对应 1.0.0-ohos-1.0.0-beta.1。
再提醒一次:仓库地址是 https://atomgit.com/oh-flutter/flutter_color_brightness,在 oh-flutter 组织下。

依赖树方面:除 Flutter SDK 外零第三方依赖,pub get 秒完成。


五、代码接入

5.1 导入库并使用

import 'package:color_brightness/color_brightness.dart';

// 变暗:每通道乘以 1 - percent/100
final Color pressed = Colors.blue.darken(10);
final Color disabled = Colors.blue.darken(40);

// 变亮:每通道向 255 线性插值 percent/100
final Color hovered = Colors.blue.lighten(10);
final Color subtleBg = Colors.blue.lighten(85);

导入即用——扩展方法直接挂在 Color 上,不需要初始化、不需要包 Widget、更不需要平台配置。

5.2 darken 与 lighten 的算法

代码逐段分析:两个方法的完整实现

Color darken([double percent = 10]) {
  assert(1 <= percent && percent <= 100);
  double x = 1 - percent / 100;
  return Color.fromARGB(
      alpha, (red * x).round(), (green * x).round(), (blue * x).round());
}

Color lighten([double percent = 10]) {
  assert(1 <= percent && percent <= 100);
  double x = percent / 100;
  return Color.fromARGB(alpha, red + ((255 - red) * x).round(),
      green + ((255 - green) * x).round(), blue + ((255 - blue) * x).round());
}
  • darken 是等比缩放:每个通道乘以 (1 - percent/100),percent=100 时得到纯黑(0,0,0);
  • lighten 是向白色的线性插值:每个通道加 (255 - 通道值) * percent/100,percent=100 时得到纯白(255,255,255);
  • 两者都以 alpha 原样构造新 Color——透明度不参与运算;
  • assert 保证 percent 落在 1~100(release 模式下断言被剥离,建议业务侧自行 clamp,示例工程就是用 value.clamp(1, 100) 再传入的)。

以真机截图验证一遍:Colors.red = #F44336,即 R=244、G=67、B=54——

  • darken(50):R = 244×0.5 = 122 = 0x7A,G = 67×0.5 = 33.5 → 34 = 0x22,B = 54×0.5 = 27 = 0x1B → #7A221B,与界面显示的 #FF7A221B(前两位 FF 是 alpha)逐位一致 ✅
  • lighten(50):R = 244 + 11×0.5 = 249.5 → 250 = 0xFA,G = 67 + 188×0.5 = 161 = 0xA1,B = 54 + 201×0.5 = 154.5 → 155 = 0x9B → #FAA19B,与界面显示的 #FFFAA19B 一致 ✅

纯 Dart 计算在鸿蒙上与 Android/iOS 逐位相同——这正是"结果确定性"类库的适配优势。

5.3 默认参数与边界值

Colors.indigo.darken();   // 等价于 darken(10)
Colors.indigo.darken(10); // 与上一行结果完全一致

percent 允许 1 与 100 两个边界:darken(100) 得纯黑、lighten(100) 得纯白,示例页的"明暗渐变"卡就用它们做了两端。

请添加图片描述

5.4 透明度保持

const Color scrim = Color(0x80F44336);      // 50% 透明的红
final Color darkerScrim = scrim.darken(20); // 依旧是 0x80 开头

遮罩、水印、半透明浮层这类"既透明又要调深浅"的场景直接受益——alpha 永远不动。

请添加图片描述

5.5 实战一:派生同源色阶

一个主色派生出一整条色阶(示例页"色阶调色板"的做法):

final Color primary = Colors.indigo;

final List<Color> scale = [
  primary.darken(80), // 最深
  primary.darken(60),
  primary.darken(40),
  primary.darken(20),
  primary,            // 锚点
  primary.lighten(20),
  primary.lighten(40),
  primary.lighten(60),
  primary.lighten(80), // 最浅
];

整条色阶与主色同一色相,视觉天然协调,适合图表系列色、进度刻度、日历热力图。

请添加图片描述

5.6 实战二:明暗双面主题

示例页"明暗主题预览"的配方——用同一主色派生亮色面与暗色面,并按亮度挑前景色:

Widget surface(BuildContext context, Color base) {
  final Color lightSurface = base.lighten(85); // 亮色面
  final Color darkSurface = base.darken(85);   // 暗色面

  return Card(
    color: lightSurface,
    child: Column(
      children: [
        Text('亮色面', style: TextStyle(color: base.darken(60))), // 深文字
        ElevatedButton(
          style: ElevatedButton.styleFrom(backgroundColor: base),
          onPressed: () {},
          child: const Text('主色按钮'),
        ),
      ],
    ),
  );
}

三点心得:亮面用 lighten 高比例拉到接近白、暗面用 darken 高比例压到接近黑;前景色按对面亮度反着选保证对比度;主按钮保持原色——同源配色让整页色调不散。

请添加图片描述

5.7 实战三:交互态一键生成

class TappableCard extends StatefulWidget {
  const TappableCard({super.key, required this.child});
  final Widget child;

  
  State<TappableCard> createState() => _TappableCardState();
}

class _TappableCardState extends State<TappableCard> {
  bool _pressed = false;

  
  Widget build(BuildContext context) {
    final Color base = Theme.of(context).colorScheme.primary;
    return GestureDetector(
      onTapDown: (_) => setState(() => _pressed = true),
      onTapUp: (_) => setState(() => _pressed = false),
      onTapCancel: () => setState(() => _pressed = false),
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 120),
        color: _pressed ? base.darken(12) : base, // 按压变深 12%
        child: widget.child,
      ),
    );
  }
}

按压态、hover 态、禁用态各配一个百分比即可,不用设计同学再出一套色值。

请添加图片描述


六、运行与验证

Demo Bundle Name:dev.kakzaki.color_brightness_example;设备:华为 TLR-AL00,HarmonyOS 6.1.0.145(API 24)。打包产物 entry-default-signed.hap(约 145 MB)。

6.1 验证一:安装与启动

hdc install -r entry-default-signed.hap
# [Info]App install path:...entry-default-signed.hap msg:install bundle successfully.

hdc shell aa start -a EntryAbility -b dev.kakzaki.color_brightness_example
# start ability successfully.

6.2 验证二:插件注册日志

hdc shell hilog | grep ColorBrightnessPlugin
10-21 10:48:05.047 W A000FF/...Flutter: FlutterEngineCxnRegistry --> Adding plugin: ColorBrightnessPlugin
10-21 10:48:05.047 I A00000/...ColorBrightnessPlugin: attached to engine, channel [color_brightness] registered

插件在引擎挂载时完成注册,通道名 color_brightness 与其余五平台逐字一致。

6.3 验证三:getPlatformVersion 无调用方(如实说明)

日志中没有出现 onMethodCall: getPlatformVersion——这是预期行为:上游设计中 Dart 层从不调用通道,原生方法只是形态一致的模板桩。业务方如需自检通道,可主动调用:

const channel = MethodChannel('color_brightness');
final String version = await channel.invokeMethod('getPlatformVersion');
// 鸿蒙真机上预期返回 "HarmonyOS 6.1.0.145"(取值优先级见第七节)

6.4 验证四:纯 Dart 计算正确性(数值核算)

界面上 Colors.red 的变换结果与手工逐通道核算完全一致(详见 5.2):darken(50) = #7A221B、lighten(50) = #FAA19B、darken() == darken(10)。同时滑动基色滑块与比例滑块,实时结果、渐变带、色阶、主题预览全部即时正确重算——纯 Dart 能力在鸿蒙上无任何折扣。

实测结论表

#验证点结果
1HAP 真机安装成功(compatibleSdkVersion 6.1.1(24))通过
2插件注册与 color_brightness 通道挂载通过
3darken(50) / lighten(50) 数值逐位正确通过
4默认参数(省略 percent = 10)通过
5alpha 保持(半透明基色变换后不变)通过
6自定义基色(任意 Color)生效通过
7getPlatformVersion 通道桩存在(Dart 层无调用方,符合上游设计)通过
8全程无需申请任何敏感权限通过

示例首页(英文) 已加载的本地化键列表 语言设置页 示例首页(英文) 示例首页(英文)


七、工作原理

调用链路

业务代码
  └─ color.darken(20) / color.lighten(20)
        └─ 纯 Dart 扩展方法(ColorBrightness on Color)
              └─ ARGB 逐通道运算 → new Color.fromARGB(alpha, r, g, b)
              ※ 不经过方法通道、不依赖平台

通道层(形态一致性保障,功能不依赖)
  └─ MethodChannel('color_brightness') / getPlatformVersion
        ├─ Android: "Android " + Build.VERSION.RELEASE
        ├─ iOS/macOS: "iOS " + systemVersion ...
        └─ OHOS: ArkTS ColorBrightnessPlugin(本次新增)
              └─ 取值优先级:
                 ① deviceInfo.distributionOSName + distributionOSVersion
                    (HarmonyOS 设备的用户可见版本,如 "HarmonyOS 6.1.0.145")
                 ② deviceInfo.osFullName
                    (OpenHarmony 设备兜底,"OpenHarmony-x.x.x.x" 已含平台名)
                 ③ "OpenHarmony API " + sdkApiVersion(最终兜底)

OHOS 插件实现

ArkTS 侧插件(ohos/src/main/ets/components/plugin/ColorBrightnessPlugin.ets)核心逻辑:

const CHANNEL_NAME: string = 'color_brightness';

export default class ColorBrightnessPlugin implements FlutterPlugin, MethodCallHandler {
  private channel: MethodChannel | null = null;

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    this.channel = new MethodChannel(binding.getBinaryMessenger(), CHANNEL_NAME);
    this.channel.setMethodCallHandler(this);
    hilog.info(DOMAIN, TAG,
      'attached to engine, channel [%{public}s] registered', CHANNEL_NAME);
  }

  onDetachedFromEngine(binding: FlutterPluginBinding): void {
    // 置空 handler 避免引擎销毁后仍持有回调,导致插件实例无法释放
    this.channel?.setMethodCallHandler(null);
    this.channel = null;
  }

  onMethodCall(call: MethodCall, result: MethodResult): void {
    if (call.method == 'getPlatformVersion') {
      result.success(this.getPlatformVersion());
    } else {
      result.notImplemented(); // 与其余平台完全一致
    }
  }

  private getPlatformVersion(): string {
    const osName = deviceInfo.distributionOSName ?? '';
    const osVersion = deviceInfo.distributionOSVersion ?? '';
    if (osName.length > 0 && osVersion.length > 0) {
      return osName + ' ' + osVersion;
    }
    if (deviceInfo.osFullName && deviceInfo.osFullName.length > 0) {
      return deviceInfo.osFullName;
    }
    return 'OpenHarmony API ' + deviceInfo.sdkApiVersion;
  }
}

代码逐段分析:取值优先级的三级兜底

OHOS 没有与 Build.VERSION.RELEASE / UIDevice.systemVersion 直接对应的单一字段。首选 distributionOSName + distributionOSVersion(HarmonyOS 设备上即用户可见的系统版本);次选 osFullName(OpenHarmony 设备的系统全名,本身已含 “OpenHarmony” 前缀,故不再重复加平台名,避免出现 OpenHarmony OpenHarmony-...);最后以 sdkApiVersion 兜底,保证任何设备都有可读返回值。这几个字段读 .d.ts 确认均无 @permission 标注——零权限。

鸿蒙技术点:纯 Dart 库为什么还需要 ohos 目录

该包以插件形态发布(pubspec 声明了 android/ios/linux/macos/windows/web 六个平台并携带原生目录)。若只缺 ohos 声明,工程在鸿蒙侧会落入"未注册插件"的形态。补齐 ohos: pluginClass: ColorBrightnessPlugin 与 ArkTS 注册类后,OpenHarmony 与其余平台的插件形态完全一致;getUniqueClassName() 与 pubspec 的 pluginClass 两侧同为 ColorBrightnessPlugin,注册链路由工具链的 GeneratedPluginRegistrant 自动完成。

适配全程遵守一条硬指标:git diff lib/ 必须为空——Dart 层零改动,这也是"纯 Dart 库鸿蒙化"验收的通用标准。


八、常见问题

Q1:darken / lighten 和 HSL 亮度调节有什么区别?

这两个方法直接在 RGB 通道上做等比缩放 / 线性插值,简单、快、结果稳定可复现;HSL/ HCT 空间的明度调节在感知上更均匀,但引入色彩空间换算。对于按压态、派生色阶这类"同一颜色变深变浅"的场景,RGB 方案完全够用且不会产生色相漂移。

Q2:percent 传 0 或者 150 会怎样?

debug 模式触发 assert(1 <= percent && percent <= 100) 断言失败;release 模式断言被剥离,行为相当于用越界系数计算(darken(0) 返回原色、darken(150) 会得到负通道值取 0 的异常颜色)。建议对滑块、输入框等动态来源先 clamp(1, 100) 再传入。

Q3:透明度会变吗?

不会。两个方法都用基色的 alpha 原样构造结果色,只改写 R/G/B——半透明遮罩调深浅时透明度保持不变(示例页"透明度保持"卡片专门验证了这一点)。

Q4:鸿蒙上 darken / lighten 的结果和 Android 一致吗?

逐位一致。计算发生在 Dart 层,与平台无关;真机实测 #F44336 → darken(50) = #7A221B、lighten(50) = #FAA19B,与算法手工核算完全吻合。

Q5:getPlatformVersion 有什么用?Dart 层为什么没有调用它?

它是 flutter create 插件模板自带的"平台自检"方法,上游六个平台都只实现了这一个方法,且 Dart 层从未调用——这是上游设计,鸿蒙侧保持一致。业务方可以通过 invokeMethod('getPlatformVersion') 主动探测插件注册是否成功,鸿蒙上预期返回 HarmonyOS <版本号>。

Q6:仓库地址到底是什么?

鸿蒙适配版在 https://atomgit.com/oh-flutter/flutter_color_brightness(oh-flutter 组织,分支 main,TAG 1.0.0-ohos-1.0.0-beta.1)。注意不是 CPF-Flutter/fluttertpc 系列,引入依赖时别写错。


九、结语

回顾一下:git TAG 引入依赖 → import 'package:color_brightness/color_brightness.dart'; → color.darken(p) / color.lighten(p) 直接用。

核心结论:

  • 库的能力是纯 Dart 的 ARGB 运算,鸿蒙上与 Android/iOS 逐位一致,真机数值核算全部通过;
  • 鸿蒙适配的实质是补齐插件工程形态(ohos 平台声明 + ArkTS 桩 + 宿主工程),Dart 层零改动(git diff lib/ 为空可验收);
  • 零权限、零第三方依赖,接入成本只有两行 import 与一次调用;
  • 已在华为真机(HarmonyOS 6.1.0.145 / API 24)完整实测,八个验证点全部通过。

欢迎提 Issue / PR 共建。


相关链接

  • 鸿蒙适配版仓库:https://atomgit.com/oh-flutter/flutter_color_brightness(TAG 1.0.0-ohos-1.0.0-beta.1,分支 main)
  • 原库:https://github.com/kakzaki/flutter_color_brightness
  • OpenHarmony deviceInfo 文档(@ohos.deviceInfo):https://developer.huawei.com/consumer/cn/doc/
  • Flutter 鸿蒙化开发环境:https://atomgit.com/oh-flutter/flutter_flutter

附:color_brightness 核心能力对照表

能力维度实现方式鸿蒙表现跨平台一致性
Color.darken(percent)纯 Dart(ARGB 等比缩放)✅ 真机数值核算通过六端逐位一致
Color.lighten(percent)纯 Dart(ARGB 线性插值)✅ 真机数值核算通过六端逐位一致
默认参数(percent = 10)纯 Dart✅ darken() == darken(10)六端一致
入参断言 1~100纯 Dart(assert)✅ 行为一致六端一致
alpha 保持纯 Dart(alpha 原样构造)✅ 透明度不变六端一致
getPlatformVersion 通道桩原生(各平台模板实现)✅ 已注册,Dart 层无调用方六端契约一致
插件注册GeneratedPluginRegistrant 自动生成✅ 引擎挂载时注册各端一致
权限要求不访问敏感能力零权限各端一致
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐