前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自学鸿蒙应用开发(34)- 为自定义UI组件增加触控处理

自学鸿蒙应用开发(34)- 为自定义UI组件增加触控处理

作者头像
面向对象思考
发布2021-04-02 11:14:34
5480
发布2021-04-02 11:14:34
举报

动作演示

除了可以描画功能之外,还可以为自定义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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档