arcview项目招募
现招募项目开发者,须使用仓颉编程语言,基于ArkUI开发的自定义组件库,实现具有弧形边缘、圆弧背景或曲线视觉效果的界面元素。
悬赏内容
招募内容
1. 核心功能开发目标
需基于仓颉语言实现与 arcview 等价的核心能力,功能清单如下(需完全覆盖且兼容 OpenHarmony API 规范):
功能模块 | 详细要求 |
|---|---|
基础弧形视图渲染 | 支持始终垂直布局、自定义最大角度(如 220°)、纯展示型 ArcView 渲染 |
弧形进度视图 | 支持手势驱动进度调整、进度值四舍五入、角度变化回调(onAngleDegreeChanged) |
视觉定制能力 | 支持弧形渐变颜色裁剪、指示器(Indicator)自定义、按钮样式 / 交互定制 |
交互兼容性 | 与 ScrollView 手势无冲突、触摸状态回调(onTouchChanged)、按钮点击回调 |
调试能力 | 支持调试日志输出、调试视图可视化 |
尺寸适配 | 支持自定义像素适配逻辑(PP,Pixel Perfect)、多设备分辨率自适应 |
2. 工程规范与技术要求
(1)开发语言与工程结构
核心代码基于仓颉语言编写,遵循《OpenHarmony 仓颉语言编码规范》;
工程结构需对齐 OpenHarmony 三方库标准,参考如下目录规范:
plaintext
arcview-cangjie/
├── library/ // 核心库代码
│ ├── src/ // 仓颉源码目录
│ │ ├── core/ // 核心逻辑层
│ │ │ ├── ArcView.ce // 基础弧形视图核心类
│ │ │ ├── ArcProgressView.ce // 弧形进度视图核心类
│ │ │ ├── GestureHandler.ce // 手势处理逻辑
│ │ │ └── SizeAdapter.ce // 尺寸适配工具类
│ │ ├── components/ // 仓颉组件层
│ │ ├── types/ // 类型定义(枚举/结构体)
│ │ └── utils/ // 工具函数(日志、像素转换等)
│ ├── example/ // 示例工程
│ └── test/ // 单元测试用例
├── oh-package.json5 // OpenHarmony 包配置
└── README.md // 文档说明
(2)核心功能代码示例
以下为关键功能的仓颉代码实现示例(需严格遵循语法规范):
① 枚举与基础类型定义
// types/ArcType.ce
/// 角度值类型定义(范围:0~360)
export type ANGLE_DEGREE = int;
/// 弧形颜色配置结构体
export struct ArcColorItem {
color: string; // 颜色值(如"#CCd0dae4")
position: float; // 渐变位置(0.0~1.0)
}
/// 弧形视图配置结构体
export struct ArcProgressViewConfig {
isDebug: bool; // 调试模式开关
steps: int; // 进度分段数
maxAngleDegree: ANGLE_DEGREE; // 最大角度
curAngleDegree: ANGLE_DEGREE; // 当前角度
enableGesture: bool; // 是否开启手势
// 尺寸配置(VP单位)
widthVp: float;
heightVp: float;
arcBgStrokeWidthVp: float;
// 颜色配置
arcBgColors: Array<ArcColorItem>;
arcOuterColors: Array<ArcColorItem>;
// 指示器配置
enableIndicator: bool;
arcIndicatorGaugeOptions: IndicatorOptions;
// 按钮配置
buttonPlusEnable: bool;
buttonMinusEnable: bool;
}
② 核心组件实现(ArcProgressView)
// components/ArcProgressView.ce
import core::ArcViewBase;
import core::GestureHandler;
import utils::Logger;
import utils::SizeAdapter;
/// 弧形进度视图组件
@Component
export struct ArcProgressView {
@Prop config: ArcProgressViewConfig;
@State curAngle: ANGLE_DEGREE;
@Link isTouching: bool;
/// 组件初始化
build() {
// 根容器(适配垂直布局)
Column() {
// 弧形绘制层
Canvas() {
// 绘制背景弧形
drawArc({
center: Point(config.widthVp/2, config.heightVp/2),
radius: config.arcBgWidthVp/2,
startAngle: 0,
sweepAngle: config.maxAngleDegree,
strokeWidth: config.arcBgStrokeWidthVp,
colors: config.arcBgColors,
isGradient: true
});
// 绘制进度弧形
drawArc({
center: Point(config.widthVp/2, config.heightVp/2),
radius: config.arcInnerWidthVp/2,
startAngle: 0,
sweepAngle: this.curAngle,
strokeWidth: config.arcInnerStrokeWidthVp,
colors: config.arcInnerColors,
isGradient: true
});
// 绘制指示器
if (config.enableIndicator) {
drawIndicator({
angle: this.curAngle,
icon: config.arcIndicatorGaugeOptions.icon,
position: calcIndicatorPosition(this.curAngle, config)
});
}
}
.width(config.widthVp)
.height(config.heightVp)
.gesture(
// 绑定手势处理(与ScrollView无冲突)
GestureHandler.buildGesture({
onPan: (offset: Point) => {
this.curAngle = calcAngleByGesture(offset, config.maxAngleDegree);
this.isTouching = true;
// 角度变化回调(四舍五入)
this.onAngleDegreeChanged(round(this.curAngle));
},
onEnd: () => {
this.isTouching = false;
}
})
)
// 自定义按钮组
Row() {
if (config.buttonMinusEnable) {
Button("-")
.onClick(() => {
this.curAngle = max(0, this.curAngle - (config.maxAngleDegree/config.steps));
this.onButtonClicked("minus");
})
}
if (config.buttonPlusEnable) {
Button("+")
.onClick(() => {
this.curAngle = min(config.maxAngleDegree, this.curAngle + (config.maxAngleDegree/config.steps));
this.onButtonClicked("plus");
})
}
}
}
.layout(LayoutMode.AlwaysVertical) // 始终垂直布局
}
/// 角度变化回调(需保证参数四舍五入)
private func onAngleDegreeChanged(newAngle: ANGLE_DEGREE) {
if (config.isDebug) {
Logger.info("ArcProgressView", "onAngleDegreeChanged: " + newAngle.toString());
}
// 对外暴露的回调触发
this.config.onAngleDegreeChanged?(newAngle);
}
/// 按钮点击回调
private func onButtonClicked(buttonType: string) {
if (config.isDebug) {
Logger.info("ArcProgressView", "onButtonClicked: " + buttonType);
}
this.config.onButtonClicked?(buttonType);
}
}
③ 尺寸适配工具(PP)
// utils/SizeAdapter.ce
/// 获取设备显示宽度
export func getDisplayWidth(): float {
let displayInfo = getHarmonyOSDisplayInfo();
return displayInfo.width;
}
/// 自定义PP适配逻辑(Pixel Perfect)
export func setCustomPP(adapter: func(px: float, designWidthPx: float) => float) {
globalPPAdapter = adapter;
}
/// PP单位转换(默认适配设计稿宽度720px)
export func pp(px: float): float {
let designWidth = 720.0;
let displayWidth = getDisplayWidth();
if (globalPPAdapter !== nil) {
return globalPPAdapter(px, designWidth);
}
// 默认适配逻辑:px转VP
return px / (designWidth / displayWidth);
}
3. 视觉与交互效果要求
需实现与原 arcview 一致的视觉表现,核心效果参考如下:
(1)核心效果图例
功能效果 | 描述 |
|---|---|
基础弧形展示 | <img src="https://github.com/krmao/arcview/raw/main/library/example/preview.gif" width="300" alt="ArcView预览效果"/> |
渐变颜色裁剪 | 弧形背景 / 进度条支持多段渐变(如 ["#CCd0dae4", 0.0], ["#EEd0dae4", 1.0]) |
指示器展示 | 进度端点显示自定义图标,支持图标与弧形的间距配置 |
手势交互 | 在 ScrollView 内滑动时,弧形进度手势无冲突,进度值实时更新 |
(2)交互细节要求
手势滑动时进度值实时更新,松手后进度值自动四舍五入到最近分段;
触摸状态回调(isTouching)需精准反映用户操作状态(按下 / 抬起);
按钮点击后进度值按分段数步进(如 15 段则每次步进 maxAngle/15)。
相关附件
质量认证要求
1. 代码质量要求
(1)语法与规范
所有代码需通过 OpenHarmony 仓颉语言语法校验工具(
cangjie-lint)检测,无语法错误、无规范违规;注释覆盖率≥80%,核心类 / 函数需包含功能描述、参数说明、返回值说明,示例代码需包含使用场景注释;
遵循 “单一职责原则”,核心逻辑拆分至独立模块(如手势处理、尺寸适配、绘制逻辑解耦)。
(2)性能要求
弧形绘制帧率≥60fps,无卡顿(在 HarmonyOS 4.0+ 真机上测试);
内存占用:组件初始化内存≤5MB,持续手势交互 1 分钟内存无泄漏;
手势响应延迟≤100ms,与 ScrollView 共存时无手势抢注问题。
2. 功能验证要求
(1)单元测试
核心函数需编写单元测试用例,测试覆盖率≥70%,涵盖:
角度计算准确性(如四舍五入、最大 / 最小角度限制);
尺寸适配逻辑(不同设备分辨率下 PP 单位转换正确性);
回调函数触发时机(角度变化、按钮点击、触摸状态)。
测试框架需使用 OpenHarmony 官方测试工具(如
ohos.test),测试报告需包含通过率、覆盖率数据。
(2)兼容性验证
适配 OpenHarmony 4.0+ 全设备形态(手机、平板、智慧屏);
兼容仓颉语言 1.0+ 版本,无 API 兼容性问题;
组件可通过
ohpm包管理器正常安装、引用,示例工程可直接编译运行。
3. 交付物质量要求
(1)代码交付
完整的仓颉语言源码(无缺失文件),工程可直接编译构建;
生成的
ohpm包需通过 OpenHarmony 三方库校验工具检测,符合发布标准;源码需提交至开源仓库,包含清晰的提交记录(按功能模块拆分提交)。
(2)文档交付
详细的 README.md(含安装指南、API 文档、使用示例、调试指南);
核心功能的演示视频 / GIF(覆盖所有关键交互场景);
性能测试报告(帧率、内存、响应延迟)、兼容性测试报告。
4. 开源规范要求
遵循 Apache 2.0 开源协议(与原
arcview一致);代码无第三方依赖(或仅依赖 OpenHarmony 官方基础库);
提交的代码需包含 CONTRIBUTORS.md,记录贡献者信息(公益性,无报酬)。
四、交付与协作方式
代码提交至指定开源仓库分支,通过 PR 进行审核;
核心功能完成后需通过功能、性能、兼容性三轮验证。

