HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件
目录:
引言
现在很多的APP会有新消息/未接来电/未读消息/新通知圆球红点提示,典型的以微信、QQ新消息提示为例,当微信朋友圈有新的朋友更新/发布朋友圈消息后,在微信的底部切换卡上会有一个红色的小圆球红点,表示有新消息,提示用户查看。在消息通讯类的app中十分实用。
功能介绍
鸿蒙BGABadgeView 徽章组件,主要功能包括:传入图片生成徽章,设置文本生成文本徽章,并且每个徽章都具有拖拽超范围即可消除,范围内即可回到原位置。模拟机效果图如下
1.图片徽章:
2.文字徽章:
3.拖动徽章爆炸:
使用时候,直接将其下载,作为一个har包导入到自己的项目中即可。下面则详细介绍BGABadgeView 的使用以及开发指南。
BGABadgeView 使用指南
Ø 新建工程, 添加组件Har包依赖
在应用模块中添加HAR,只需要将verificationcodeview-debug.har复制到entry\libs目录下即可
Ø 修改配置文件
1. 修改主页面的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<DependentLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:id="$+id:layout1"
ohos:orientation="vertical">
<DependentLayout
ohos:id="$+id:dependent1"
ohos:height="200vp"
ohos:width="match_parent">
<com.example.bgabadgecomp_library.BAGDragBadgeImage
ohos:top_margin="15vp"
ohos:right_margin="10vp"
ohos:bottom_margin="10vp"
ohos:height="80vp"
ohos:width="80vp"
ohos:scale_mode="zoom_center"
ohos:image_src="$media:avator"
ohos:id="$+id:image1"
ohos:below="$id:title"
ohos:left_margin="30vp"/>
<Image
ohos:top_margin="15vp"
ohos:right_margin="10vp"
ohos:bottom_margin="10vp"
ohos:height="80vp"
ohos:width="80vp"
ohos:scale_mode="zoom_center"
ohos:image_src="$media:avator"
ohos:id="$+id:image2"
ohos:end_of="$id:image1"
ohos:below="$id:title"
ohos:left_margin="10vp"/>
</DependentLayout>
<Text
ohos:left_margin="30vp"
ohos:id="$+id:text1"
ohos:top_margin="10vp"
ohos:right_margin="15vp"
ohos:bottom_margin="10vp"
ohos:height="40vp"
ohos:width="match_parent"
ohos:text="测试1"
ohos:below="$id:dependent1"
ohos:text_size="20vp"/>
</DependentLayout>
2.修改MainAbilitySlice中的UI加载代码
在MainAbilitySlince类的onStart函数中,增加如下代码:
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
BAGDragBadgeImage bagDragBadgeImage = (BAGDragBadgeImage) findComponentById(ResourceTable.Id_image1);
bagDragBadgeImage.setCornerRadius(bagDragBadgeImage.getWidth() / 2); // 圆形边框
DependentLayout stackLayout = (DependentLayout) findComponentById(ResourceTable.Id_layout1);
Image image2 = (Image) findComponentById(ResourceTable.Id_image2);
image2.setCornerRadius(20);
DependentLayout.LayoutConfig config = new DependentLayout.LayoutConfig(DependentLayout.LayoutConfig.MATCH_PARENT, DependentLayout.LayoutConfig.MATCH_PARENT);
RoundRectImage roundRectImage = RoundRectImage.attach2Window(this, stackLayout, image2, config, BGABadgeViewHelper.getPixelMap(this, ResourceTable.Media_avatar_vip));
RoundRectText roundRectText = RoundRectText.attach2Window(this, stackLayout, image3, config);
Text text1 = (Text) findComponentById(ResourceTable.Id_text1);
RoundRectText roundText1 = RoundRectText.attach2Window(this, stackLayout, text1, config);
roundText1.setBadgeText("qqqqqqqq");
List<Component> componentList = new ArrayList<>();
componentList.add(roundRectText);
componentList.add(roundText1);
stackLayout.setTouchEventListener(new Component.TouchEventListener() {
@Override
public boolean onTouchEvent(Component component, TouchEvent event) {
switch (event.getAction()) {
case TouchEvent.PRIMARY_POINT_DOWN:// 手指第一次触摸到屏幕
int startX = (int) event.getPointerPosition(event.getIndex()).getX();
int startY = (int) event.getPointerPosition(event.getIndex()).getY();
if (startX < roundRectImage.getCircleLeft() + 2 * roundRectImage.getCircleRadius()
&& startX > roundRectImage.getCircleLeft()
&& startY < roundRectImage.getCircleTop() + 2 * roundRectImage.getCircleRadius()
&& startY > roundRectImage.getCircleTop()) {
roundRectImage.setDraggedListener(DRAG_HORIZONTAL_VERTICAL, roundRectImage );
for (Component component1 : componentList) {
component1.setDraggedListener(DRAG_HORIZONTAL_VERTICAL,null);
}
} else {
roundRectImage.setDraggedListener(DRAG_HORIZONTAL_VERTICAL, null );
for (Component component1 : componentList) {
RoundRectText rectText = (RoundRectText) component1;
if (startX < rectText.getCircleLeft() + 2 * rectText.getRadius()
&& startX > rectText.getCircleLeft()
&& startY < rectText.getCircleTop() + 2 * rectText.getRadius()
&& startY > rectText.getCircleTop()) {
component1.setDraggedListener(DRAG_HORIZONTAL_VERTICAL, (Component.DraggedListener) component1);
} else {
component1.setDraggedListener(DRAG_HORIZONTAL_VERTICAL,null);
}
}
}
break;
case TouchEvent.PRIMARY_POINT_UP:
case TouchEvent.POINT_MOVE:
default:
break;
}
return true;
}
});
}
通过以上两个步骤,就实现了简单的徽章组件,接下来在一起看下徽章组件是如何实现的。
BGABadgeView 开发指南
新建一个Module
新建一个Module,类型选择HarmonyOS Library,模块名为VerificationCodeView,如图:
新建一个RoundRectText类
1.实现自定义RoundRectText绘制
@Override
public void onDraw(Component component, Canvas canvas){
length = mBadgeText.length();
Paint mTextPain = new Paint();
mTextPain.setColor(Color.WHITE);
mTextPain.setStyle(Paint.Style.FILL_STYLE);
mTextPain.setTextSize(30);
mTextPain.setFont(Font.DEFAULT);
Rect textBounds = mTextPain.getTextBounds(mBadgeText);
Paint mBadgePaint = new Paint();
mBadgePaint.setColor(Color.RED);
mBadgePaint.setStyle(Paint.Style.FILL_STYLE);
mBadgePaint.setStrokeWidth(5);
if (mBadgeRectF == null) {
switch (mBadgeGravity) {
case RightTop:
int left = mComponent.getLeft();
int top = mComponent.getTop();
circleLeft = mComponent.getWidth() + left - 2 * radius - 15 * (length - 2);
circleTop = top;
mBadgeRectF = new RectFloat( circleLeft, circleTop, circleLeft + 2 * radius + 15 * (length - 2) , circleTop + 2 * radius);
break;
case RightCenter:
left = mComponent.getLeft();
top = mComponent.getTop();
circleLeft = mComponent.getWidth() + left - 2 * radius - 15 * (length - 2);
circleTop = top + (float)mComponent.getHeight() / 2 - radius;
mBadgeRectF = new RectFloat( circleLeft, circleTop, circleLeft + 2 * radius + 15 * (length - 2) , circleTop + 2 * radius);
break;
case RightBottom:
mBadgeRectF = new RectFloat();
left = mComponent.getLeft();
top = mComponent.getTop();
circleLeft = mComponent.getWidth() + left - 2 * radius - 15 * (length - 2) ;
circleTop = top + mComponent.getHeight() - 2 * radius;
mBadgeRectF = new RectFloat( circleLeft, circleTop, circleLeft + 2 * radius + 15 * (length - 2) , circleTop + 2 * radius);
break;
default:
break;
}
}
path = (float) Math.sqrt((mBadgeRectF.left - circleLeft) * (mBadgeRectF.left - circleLeft) + (mBadgeRectF.top - circleTop) * (mBadgeRectF.top - circleTop));
isOverPath = path > overPath;
float offSet = (float) (textBounds.top + textBounds.bottom) / 2;
float boundsX = 0 ;
if( 15 * length < (mBadgeRectF.right - mBadgeRectF.left)){
float temp = mBadgeRectF.right - mBadgeRectF.left - 15 * length;
boundsX = temp / 2;
}
float roundNum = 2 * radius / (mBadgeRectF.right - mBadgeRectF.left) ;
canvas.drawRoundRect(mBadgeRectF,roundNum * radius ,roundNum * radius, mBadgePaint);
canvas.drawText(mTextPain, mBadgeText, mBadgeRectF.left + boundsX, mBadgeRectF.top + radius - offSet);
}
2.生成拖拽事件
@Override
public void onDragDown(Component component, DragInfo dragInfo) {
pointX = dragInfo.downPoint.getPointX();
pointY = dragInfo.downPoint.getPointY();
if (pointX <= circleLeft || pointX >= circleLeft + 2 * radius + 15 * (length - 2)
|| pointY <= circleTop || pointY >= circleTop + 2 * radius) {
onDragCancel(component, dragInfo);
}
}
@Override
public void onDragStart(Component component, DragInfo dragInfo) {
}
@Override
public void onDragUpdate(Component component, DragInfo dragInfo) {
float left = mBadgeRectF.left;
float right = mBadgeRectF.right;
float top = mBadgeRectF.top;
float bottom = mBadgeRectF.bottom;
if (pointX <= circleLeft || pointX >= circleLeft + 2 * radius + 15 * (length - 2)
|| pointY <= circleTop || pointY >= circleTop + 2 * radius) {
onDragCancel(component, dragInfo);
} else {
mBadgeRectF.left = (float) (left + dragInfo.xOffset);
mBadgeRectF.right = (float) (right + dragInfo.xOffset);
mBadgeRectF.top = (float) (top + dragInfo.yOffset);
mBadgeRectF.bottom = (float) (bottom + dragInfo.yOffset);
invalidate();
}
}
@Override
public void onDragEnd(Component component, DragInfo dragInfo) {
if (isOverPath) {
explosionField.explode(component, mBadgeRectF, explosionFieldColor);
} else {
mBadgeRectF = new RectFloat(circleLeft, circleTop , circleLeft + 2 * radius + 15 * (length - 2), circleTop + 2 * radius);
invalidate();
}
}
@Override
public void onDragCancel(Component component, DragInfo dragInfo) {
mBadgeRectF = new RectFloat(circleLeft, circleTop , circleLeft + 2 * radius + 15 * (length - 2), circleTop + 2 * radius);
invalidate();
}
具体代码请下载项目查看。
编译HAR包
利用Gradle可以将HarmonyOS Library库模块构建为HAR包,构建HAR包的方法如下:
在Gradle构建任务中,双击PackageDebugHar或PackageReleaseHar任务,构建Debug类型或Release类型的HAR。
待构建任务完成后,可以在工程目录中的VerificationCodeView> bulid > outputs > har目录中,获取生成的HAR包。
更多原创,请关注:软通动力HarmonyOS学院https://harmonyos.51cto.com/column/30
作者:软通田可辉
想了解更多内容,请访问51CTO和华为合作共建的鸿蒙社区:https://harmonyos.51cto.com
HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件的更多相关文章
- HarmonyOS三方件开发指南(15)-LoadingView功能介绍
目录: 1. LoadingView组件功能介绍2. Lottie使用方法3. Lottie开发实现4.<HarmonyOS三方件开发指南>系列文章合集 1. LoadingView组件功 ...
- HarmonyOS三方件开发指南(12)——cropper图片裁剪
鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 目录:1. cropper组件功能介绍2. cropper使用方法3. cropper组件开发实现4. ...
- HarmonyOS三方件开发指南(13)-SwipeLayout侧滑删除
鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 目录:1. SwipeLayout组件功能介绍2. SwipeLayout使用方法3. SwipeLa ...
- HarmonyOS三方件开发指南(14)-Glide组件功能介绍
<HarmonyOS三方件开发指南>系列文章合集 引言 在实际应用开发中,会用到大量图片处理,如:网络图片.本地图片.应用资源.二进制流.Uri对象等,虽然官方提供了PixelMap进行图 ...
- HarmonyOS三方件开发指南(16)-VideoCache 视频缓存
目录: 1.引言 2.功能介绍 3.VideoCache使用指南 4.VideoCache开发指南 5.<HarmonyOS三方件开发指南>系列文章合集 引言 对于视频播放器这个app大家 ...
- HarmonyOS三方件开发指南(17)-BottomNavigationBar
目录: 1.引言 2.功能介绍 3.BottomNavigationBar使用指南 4.BottomNavigationBar开发指南 5.<HarmonyOS三方件开发指南>文章合集 引 ...
- HarmonyOS三方件开发指南(4)——Logger组件
目录: 1. Logger功能介绍 2. Logger使用方法 3. Logger开发实现 4. 源码上传地址 1. Logger功能介绍1.1. ...
- HarmonyOS三方件开发指南(5)——Photoview组件
PhotoView使用说明 1. PhotoView功能介绍1.1 组件介绍: PhotoView是一个继承自Image的组件,不同之处在于:它可以进行图击放大功能,手势缩放功能(暂无 ...
- HarmonyOS三方件开发指南(7)——compress组件
目录:1. 组件compress功能介绍2. 组件compress使用方法3. 组件compress开发实现 1. 组件compress功能介绍1.1. 组件介绍: compress是 ...
随机推荐
- 翻译:《实用的Python编程》04_02_Inheritance
目录 | 上一节 (4.1 类) | 下一节 (4.3 特殊方法) 4.2 继承 继承(inheritance)是编写可扩展程序程序的常用手段.本节对继承的思想(idea)进行探讨. 简介 继承用于特 ...
- 苹果M1处理器Mac“翻车”:用户吐槽SSD
SSD如今被不少PC用户所推崇,其优势在于读写速度快.工作无噪音,不过,缺点是寿命较机械硬盘差点.厂商对SSD通常都会标注一个最大可写入量(TBW),提醒用户关注健康数据,以免掉盘等严重问题. 越来越 ...
- 如何快速的插入 100W数据到数据库,使用PreparedStatement 最快实现!
有时候,我们使用数据库的时候,如何快速的添加测试数据到数据库中,做测试呢,添加100W 数据,如果使用工具的话可能很慢,这里我推荐大家使用 PreparedStatement 预编译 去进行操作:单线 ...
- WS1008网络损伤测试仪
WS1008网络损伤测试仪具备高性能的网络损伤仿真功能.冗余链路测试功能和线速流量生成功能,提供了综合性的网络系统测试方案,可充分测试.验证网络系统的抗损伤能力.链路切换能力及数据转发能力.为高可靠性 ...
- java mvc 及其缓存
使用Spring框架的好处是什么? - 轻量:Spring 是轻量的,基本的版本大约2MB. - 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们. ...
- 攻防世界 reverse serial-150
serial-150 suctf-2016 直接使用ida发现main函数中夹杂大片数据,应该是自修改代码,动态调试: 调试中发现,输入为16位,验证方法为:从头开始取一字符进行比较,比较通过检验后, ...
- electron踩坑系列之一
前言 以electron作为基础框架,已经开发两个项目了.第一个项目,我主要负责用react写页面,第二项目既负责electron部分+UI部分. 做项目,就是踩坑, 一路做项目,一路踩坑,坑多不可怕 ...
- 快速上手阿里云oss SDK
使用阿里云oss SDK 依赖安装: pip install oss2 pip install aliyun-python-sdk-sts 版本最好是 2.7.5 或以上 如果要开启 crc64 循环 ...
- for what? while 与 until 差在哪?-- Shell十三问<第十三问>
for what? while 与 until 差在哪?-- Shell十三问<第十三问> 最后要介绍的是 shell script 设计中常见的"循环"(loop). ...
- 全网最详细的新手入门Mysql命令和基础,小白必看!
MySQL简介 什么是数据库 ? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅仅是 ...