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

  • 相关阅读:
    101. Symmetric Tree(js)
    100. Same Tree(js)
    99. Recover Binary Search Tree(js)
    98. Validate Binary Search Tree(js)
    97. Interleaving String(js)
    96. Unique Binary Search Trees(js)
    95. Unique Binary Search Trees II(js)
    94. Binary Tree Inorder Traversal(js)
    93. Restore IP Addresses(js)
    92. Reverse Linked List II(js)
  • 原文地址:https://www.cnblogs.com/HarmonyOS/p/14744384.html
Copyright © 2011-2022 走看看