首页 / 行业
HarmonyOS 中的几个自定义控件介绍
2022-01-04 13:49:00

HarmonyOS 开发自定义组件目前还不是很丰富,在开发过程中常常会有一些特殊效果的组件,这就需要我们额外花一些时间实现。
这里给大家提供了一个 BottomSheet 上拉抽屉的组件,同时通过这个组件示例讲解一下 HarmonyOS 中的几个自定义控件用到的知识,分享一下自己自定义组件的思路。
效果演示如下图:
实现思路
①布局设计
选择的是相对布局,蒙层区来改变内容区随着抽屉的位置调节透明度。如图 1:
②手势判断
先得出 Component 在屏幕的上下左右的坐标,然后手指的坐标是否在 Component 内。
/***(x,y)是否在view的区域内**@paramcomponent*@paramx*@paramy*@return*/privatebooleanisTouchPointInComponent(Componentcomponent,floatx,floaty){int[]locationOnScreen=component.getLocationOnScreen();intleft=locationOnScreen[0];inttop=locationOnScreen[1];intright=left+component.getEstimatedWidth();intbottom=top+component.getEstimatedHeight();booleaninY=y>=top&&y<= bottom; boolean inX = x >=left&&x<= right; return inY && inX;}
③抽屉偏移
步骤如下:
这里采用的是整个 component 对 Touch 事件的监听。
手指按下的判断是否在抽屉上,然后记录当前触摸 y 坐标。
移动是算出偏移量 offY。
setTouchEventListener(newTouchEventListener(){@OverridepublicbooleanonTouchEvent(Componentcomponent,TouchEventtouchEvent){HiLog.info(logLabel,"onTouchEventaction:"+touchEvent.getAction());switch(touchEvent.getAction()){caseTouchEvent.PRIMARY_POINT_DOWN:marginBottom=directionalLayout.getMarginBottom();MmiPointposition=touchEvent.getPointerScreenPosition(0);if(isTouchPointInComponent(directionalLayout,position.getX(),position.getY())){dragStartPointY=touchEvent.getPointerPosition(0).getY();returntrue;}break;caseTouchEvent.PRIMARY_POINT_UP:onTouchUp();break;caseTouchEvent.POINT_MOVE:floaty=touchEvent.getPointerPosition(0).getY();floatoffY=dragStartPointY-y;setDrawerMarginBottom((int)offY);break;}returnfalse;}});
根据偏移量改变抽屉的位置:
privatevoidsetDrawerMarginBottom(intoffY){intbottom=marginBottom+offY;if(bottom>0){bottom=0;listContainer.setEnabled(true);}if(bottom< -H / 2) { bottom = -H / 2; } HiLog.info(logLabel, "setDrawerMarginBottom bottom:" + bottom); float alpha = (0.5f - Math.abs((float) bottom / (float) H)) * 0.5f; HiLog.info(logLabel, "setDrawerMarginBottom alpha:" + alpha); bgComponent.setAlpha(alpha); directionalLayout.setMarginBottom(bottom);}
④事件冲突解决
首先发现不能按安卓的思想去处理:
HarmonyOS 中是没有事件分发这概念的,只有事件消费,ListContainer 先拿到事件,然后是抽屉布局。
根据抽屉在完全展开的位置,在 ListContainer 收到触摸事件时,把 ListContainer 事件静止掉,不让其消费。
待抽屉完全展开时,解开 ListContainer 的事件。
listContainer.setTouchEventListener(newTouchEventListener(){@OverridepublicbooleanonTouchEvent(Componentcomponent,TouchEventtouchEvent){marginBottom=directionalLayout.getMarginBottom();booleandrag_down=listContainer.canScroll(DRAG_DOWN);booleandrag_UP=listContainer.canScroll(DRAG_UP);if(marginBottom==0&&drag_down){component.setEnabled(true);returntrue;}component.setEnabled(false);returnfalse;}});
这里是抽屉容器定位抽屉时,判断是否打开 ListContainer 事件。
privatevoidsetDrawerMarginBottom(intoffY){intbottom=marginBottom+offY;if(bottom>0){bottom=0;listContainer.setEnabled(true);}.......}
⑤背景亮暗变化
首先我们 XML 布局参照上述布局设计—如图 1。背景亮暗的改变根据抽屉位置按比例设置蒙层的透明度。
floatalpha=(0.5f-Math.abs((float)bottom/(float)H))*0.5f;bgComponent.setAlpha(alpha);
⑥回弹效果
运用到了数值动画,在手势抬起时,判断上下临界点决定动画的上下。
privatevoidonTouchUp(){HiLog.info(logLabel,"onTouchUp");createAnimator();}
privatevoidcreateAnimator(){marginBottom=directionalLayout.getMarginBottom();HiLog.info(logLabel,"createAnimatormarginBottom:"+marginBottom);//创建数值动画对象AnimatorValueanimatorValue=newAnimatorValue();//动画时长animatorValue.setDuration(300);//播放前的延迟时间animatorValue.setDelay(0);//循环次数animatorValue.setLoopedCount(0);//动画的播放类型animatorValue.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);//设置动画过程animatorValue.setValueUpdateListener(newAnimatorValue.ValueUpdateListener(){@OverridepublicvoidonUpdate(AnimatorValueanimatorValue,floatvalue){HiLog.info(logLabel,"createAnimatorvalue:"+value);if(marginBottom>-H/4){//topHiLog.info(logLabel,"createAnimatortop:"+value);setDrawerBottomOrToP((int)(marginBottom-value*marginBottom));}else{//bottomHiLog.info(logLabel,"createAnimatorbottom:"+value);inttop=H/2+marginBottom;setDrawerBottomOrToP((int)(marginBottom-value*top));}}});//开始启动动画animatorValue.start();}
privatevoidsetDrawerBottomOrToP(intbottom){if(bottom>0){bottom=0;listContainer.setEnabled(true);}if(bottom< -H / 2) { bottom = -H / 2; } float alpha = (0.5f - Math.abs((float) bottom / (float) H)) * 0.5f; bgComponent.setAlpha(alpha); directionalLayout.setMarginBottom(bottom);}
总结
自定义组件步骤及思考方向:
明确父容器和子 view 的关系。
如何绘制一般采用以下三个方向:已有控件组合;采用画布绘制等;继承控件扩展功能。
若涉及到触摸事件,需要考虑如何处理事件分发与消费。
动画选择,可根据需求选择合适动画(本文采用属性动画)。
计算问题,复杂的需要丰富的数学知识。
性能问题(过度计算,重复绘制,对象重复创建)。
代码地址:
https://gitee.com/guangdong-wangduoyu/touch-event-demo
原文标题:HarmonyOS“上拉抽屉”效果实现!
文章出处:【微信公众号:HarmonyOS技术社区】欢迎添加关注!文章转载请注明出处。
审核编辑:彭菁最新内容
- Efuse是什么?聊聊芯片级的eFuse
- 英飞凌推出XENSIV胎压传感器,满足智能胎压监测系统的需
- FPGA学习笔记:逻辑单元的基本结构
- 创造多样信号的万能工具:函数/任意波形发生器
- 位移传感器结构类型及工作原理与应用
- 开关电源供应器的功能、应用场景以及重要性
- 重庆东微电子推出高性能抗射频干扰MEMS硅麦放大器芯片
- 拒绝一次性芯片,新技术:无线升级芯片
- 芯片迈向系统化时代:EDA软件的创新之路
- 智能安全帽功能-EIS智能防抖摄像头4G定位生命体征监测
- 卫星应用受关注,GNSS导航芯片/模块发展加速
- AI边缘智能分析设备:智慧食堂明厨亮灶的智能化应用
- 美光低功耗内存解决方案助力高通第二代骁龙XR2平台
- 浅谈芯片常用的解密器
- 电路板技术水平和质量水平,影响着机器人赛道的发展前景
- 直播回顾 | 宽禁带半导体材料及功率半导体器件测试
- 写flash芯片时为什么需要先擦除?
- DigiKey 凭借品牌更新荣获四项 MarCom 大奖
- 高精度3D视觉技术,助力工业机器人实现汽车零部件高效上
- 不只是芯片 看看传感器技术我们离世界顶级有多远
- 加特兰毫米波雷达SoC芯片赋能室内安防新应用
- 所有遥不可及,终因AI触手可及
- 一种基于聚合物的化学电阻式传感器使患者检测更容易
- MTK天玑9300重磅发布:全大核时代到来,330亿参数AI大模型
- 如何测量温度传感器的好坏?
- ACCEL光电芯片,性能超GPU千倍,新一代计算架构将更早来临
- 如何利用示波器快速测量幅频特性?有何注意事项?
- 射频连接器使用技巧与注意事项
- STC15W芯片A/D、D/A转换的简单使用
- 群芯微车规级认证的光电耦合器备受电池BMS和电驱电控
- 芯朋微:服务器配套系列芯片已通过客户验证 可应用于AI
- 新能源高压连接器高压互锁(HVIL)功能详解
- FPGA和AI芯片算哪一类?芯片的不同分类方式
- MPS全系列电机驱动产品,助力新能源汽车实现更好的智能
- 基于穿隧磁阻效应(TMR)的车规级电流传感器
- 豪威发布新款 4K 分辨率图像传感器,适用于安防摄像头
- 苹果发布M3系列新款MacBook Pro/iMac:业界首批PC 3nm芯
- 硅谷:设计师利用生成式 AI 辅助芯片设计
- 电容式触摸按键屏中应用的高性能触摸芯片
- DigiKey 推出《超越医疗科技》视频系列的第一季

手机 |
相关内容
华为或在开发全新海思麒麟芯片,今
华为或在开发全新海思麒麟芯片,今年新机或不能采用此平台,用此,新海,芯片,平台,麒麟,研发,华为是一家全球知名的科技公司,其海思麒麟能测好几个地方的温度的电温度表电
能测好几个地方的温度的电温度表电路,电路图,信号处理电子电路图,能测好几个地方的温度的电温度表电路 温度,表,能测好几个地方的温由CMOS组件构成的文氏桥振荡器
由CMOS组件构成的文氏桥振荡器,电路图,信号处理电子电路图,由CMOS组件构成的文氏桥振荡器 振荡器,由CMOS组件构成的文氏桥振荡器CMOS组件构成的倍频器
CMOS组件构成的倍频器,电路图,信号处理电子电路图,CMOS组件构成的倍频器 倍频器,CMOS组件构成的倍频器可遥控清零的四位遥控组件设计方案
可遥控清零的四位遥控组件设计方案,电路图,遥控电路图,可遥控清零的四位遥控组件设计方案 遥控,可遥控清零的四位遥控组件设计方案动态甲类偏置组件的原理和使用
动态甲类偏置组件的原理和使用,电路图,可控硅电路图,电子开关电路图,动态甲类偏置组件的原理和使用 动态,甲类,偏置,动态甲类偏置组ZF三相电动机换相组件可逆电动机电
ZF三相电动机换相组件可逆电动机电路图,电路图,电动机控制电路图,ZF三相电动机换相组件可逆电动机电路图 ZF 电动机,ZF三相电动机换几个555定时器应用电路图
几个555定时器应用电路图,电路图,555集成电路大全,几个555定时器应用电路图 555定时器,延时电路,电子门铃,555定时器具有成本低,性能