动作演示
除了可以描画功能之外,还可以为自定义UI组件增加各种响应,本文以触控事件进行说明。先看演示效果:
构建事件转发类
本文通过构建一个内置TouchEventListener类实现对触控事件的接收和转发。
代码语言:javascript复制
代码语言:javascript复制public class ArcProgressBarContainer extends ComponentContainer implements Component.DrawTask {
// HiLogLabel
private static final HiLogLabel Label = new HiLogLabel(HiLog.LOG_APP, 0x00101, "RoundProgressBarContainer");
private TouchEventListener mTouchEventListener = (component, touchEvent) -> this.onTouchEvent(component, touchEvent);
private int active_bar = 1;
public ArcProgressBarContainer(Context context) {
super(context);
addDrawTask(this);
setTouchEventListener(mTouchEventListener);
}
代码第11行通过setTouchEventListener将内置的TouchEventListener指定为触控事件监听器。
处理触控事件
本例只需要处理触控开始事件:
代码语言:javascript复制
代码语言:javascript复制public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
switch (touchEvent.getAction()) {
case TouchEvent.PRIMARY_POINT_DOWN: {
MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
active_bar = hitTest(getComponentPoint(point));
invalidate();
HiLog.warn(Label, "point=%{public}f,%{public}f,hit=%{public}d",
point.getX(), point.getY(), active_bar);
return true;
}
case TouchEvent.PRIMARY_POINT_UP:
HiLog.debug(Label, "TouchEvent.PRIMARY_POINT_UP");
break;
case TouchEvent.POINT_MOVE: {
HiLog.debug(Label, "TouchEvent.POINT_MOVE");
MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
break;
}
}
return false;
}
代码第4行获得触控坐标之后,使用如下面代码所示的getComponentPoint将其转换为组件内坐标之后,调用hitTest方法计算选中的进度条。
代码语言:javascript复制
代码语言:javascript复制private MmiPoint getComponentPoint(MmiPoint point){
return new MmiPoint(point.getX() - getLeft(), point.getY() - getTop());
}
private int hitTest(MmiPoint point){
int hit = -1;
for(int i = 0; i < getChildCount(); i){
RectFloat barRect = getProgressRect(i);
Point center = barRect.getCenter();
float radius = barRect.getWidth() / 2;
float distance = (float) Math.sqrt((point.getX() - center.getPointX()) * (point.getX() - center.getPointX())
(point.getY() - center.getPointY()) * (point.getY() - center.getPointY()));
HiLog.warn(Label, "distance=%{public}f", distance);
if(distance <= radius){
hit = i;
}
else{
break;
}
}
return hit;
}
需要注意的是,由于这几个进度条相互重叠,hitTest代码采用由外向内计算距圆心距离的方式寻找选中的进度条。
参考代码
完整代码可以从以下链接下载:
https://github.com/xueweiguo/Harmony/tree/master/CustomizeComponent