zoukankan      html  css  js  c++  java
  • HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件

    目录:

    1、引言

    2、功能介绍

    3、BGABadgeView 使用指南

    4、BGABadgeView 开发指南

    5、《HarmonyOS三方件开发指南》系列文章合集

    引言

    现在很多的APP会有新消息/未接来电/未读消息/新通知圆球红点提示,典型的以微信、QQ新消息提示为例,当微信朋友圈有新的朋友更新/发布朋友圈消息后,在微信的底部切换卡上会有一个红色的小圆球红点,表示有新消息,提示用户查看。在消息通讯类的app中十分实用。

    功能介绍

    鸿蒙BGABadgeView 徽章组件,主要功能包括:传入图片生成徽章,设置文本生成文本徽章,并且每个徽章都具有拖拽超范围即可消除,范围内即可回到原位置。模拟机效果图如下

    1.图片徽章:

    【软通动力】HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件【软通动力】HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件

    2.文字徽章:

    【软通动力】HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件

    3.拖动徽章爆炸:【软通动力】HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件

    使用时候,直接将其下载,作为一个har包导入到自己的项目中即可。下面则详细介绍BGABadgeView 的使用以及开发指南。

    BGABadgeView 使用指南

    Ø 新建工程, 添加组件Har包依赖

    在应用模块中添加HAR,只需要将verificationcodeview-debug.har复制到entrylibs目录下即可

    Ø 修改配置文件

    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,如图:

    【软通动力】HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件新建一个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三方件开发指南(19)-BGABadgeView徽章组件

    更多原创,请关注:软通动力HarmonyOS学院https://harmonyos.51cto.com/column/30

    作者:软通田可辉

    想了解更多内容,请访问51CTO和华为合作共建的鸿蒙社区:https://harmonyos.51cto.com

  • 相关阅读:
    Codeforces Round #256 (Div. 2/B)/Codeforces448B_Suffix Structures(字符串处理)
    【android】优秀的UI资源站点集合
    升级iOS8系统后,保险箱Pro、私人保险箱、私密相冊打开就闪退的官方解决方式
    js产生随机数
    java实现各种数据统计图(柱形图,饼图,折线图)
    Matlab画图-非常具体,非常全面
    Lucene教程具体解释
    NAND FLASH
    Jenkins(二)
    iOS 本地通知
  • 原文地址:https://www.cnblogs.com/HarmonyOS/p/14744384.html
Copyright © 2011-2022 走看看