0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于安卓的滑动拼图验证组件实现鸿蒙化迁移和重构

OpenHarmony技术社区 来源:鸿蒙技术社区 作者:朱伟ISRC 2021-11-01 14:23 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

基于安卓平台的滑动拼图验证组件 SwipeCaptcha,实现了鸿蒙化迁移和重构,代码已经开源,目前已经获得了很多人的 Star 和 Fork ,欢迎各位下载使用并提出宝贵意见!

开源地址:
https://gitee.com/isrc_ohos/swipe-captcha_ohos

在页面登录或者注册的时候,为了确保不是机器人操作,会让用户手动验证。

验证方式分为滑动拼图验证和滑动验证两种:

  • 滑动拼图验证:有图片作为背景,通过图块拼接实现安全验证。

  • 滑动验证:无图片背景,只拖动滑块便可实现安全验证。

本文的 SwipeCaptcha_ohos2.0 组件属于滑动拼图验证,操作简单,安全性强,可被应用于各种网站的登录、注册、找回密码或投票等场景中。

我们之前已经实现了滑动拼图验证组件 SwipeCaptcha_ohos,相关文章可查看《鸿蒙页面滑动组件,代码已开源!》 。

本次 SwipeCaptcha_ohos2.0 是基于之前移植的项目进行了相关功能的优化,具体优化内容将在下文中详细介绍。

组件效果展示

SwipeCaptcha_ohos2.0 的主要功能和之前的 SwipeCaptcha_ohos 基本一致,组件在使用时,有两个较为重要的元素:滑块和原图。

二者被放置于同一水平线上,用户拖动滑块至原图处使二者重合,误差小于提前设定的验证阈值,即可验证成功。每次调用组件,滑块和原图的位置都会发生随机变化。

SwipeCaptcha_ohos2.0 相较于之前的版本,大幅提升了组件功能的完整性以及使用体验。

下面将依次从组件验证失败和验证成功两个状态,展示 SwipeCaptcha_ohos2.0 与之前版本的效果对比。

①验证失败

通过图 1(a) 和图 1(b) 的对比可以看出,新版本移除了旧版本中“当前进度值预览”的不必要功能以及下方的状态栏。

取而代之的功能如下:
  • 验证滑块由正方形小块升级为“拼图块”样式。

  • 待验证背景图块增加了阴影遮罩效果。

  • 验证失败后增加了滑块闪烁效果以及“验证失败,请重新验证!”的弹窗提醒。

②验证成功

通过图 2(a) 和图 2(b) 的对比可以看出,新版本移除了旧版本中“当前进度值预览”的不必要功能以及下方的状态栏。

取而代之的功能如下:
  • 点击“重新生成验证码”按钮后,滑块和原图的位置都会发生随机变化。

  • 验证成功后增加了反光条划过的动画效果以及“验证成功!”的弹窗提醒。

除了上述直观的功能优化外,SwipeCaptcha_ohos2.0 还实现了以下功能:
  • 滑块大小和容错阈值的用户自定义:滑块大小自定义是指用户可以通过代码自定义滑块的宽高;容错阈值自定义是指用户可以通过代码自定义匹配时的容错率,即相差多少视作匹配成功。

  • 拼图背景在指定范围内的自适应填充:原组件的图片不能在指定组件宽高的前提下自动填充图片,如果强行适配宽高会出现拼图块内容错位的情况;经过改进后,验证图片已经能够适配布局中规定的组件宽高。

Sample 解析

通过上文相信大家已经了解 SwipeCaptcha_ohos2.0 组件的使用效果,下面将具体讲解 SwipeCaptcha_ohos2.0 组件的使用方法。

共分为如下 5 个步骤:
  • 步骤 1:导入 SwipeCaptchaView 类并声明类对象。

  • 步骤 2:在 xml 文件中添加 SwipeCaptchaView 控件。

  • 步骤 3:绑定 SwipeCaptchaView 控件。

  • 步骤 4:设置回调处理函数。

  • 步骤 5:设置 Button 控件监听事件,重新生成验证区域。

①导入 SwipeCaptchaView 类并声明类对象

在 MainAbilitySlice.java 文件中,通过 import 关键字导入 SwipeCaptchaView 类。

//导入SwipeCaptchaView类
importcom.huawei.swipecaptchaview.lib.SwipeCaptchaView;
publicclassMainAbilitySliceextendsAbilitySlice{
//声明SwipeCaptchaView类对象
SwipeCaptchaViewswipeCaptchaView;
......
}

②在 xml 文件中添加 SwipeCaptchaView 控件

在 xml 文件中添加 SwipeCaptchaView 控件,用于显示滑动验证的背景图和动态效果。设置控件高和宽、滑块的高和宽以及验证阈值等属性。

"http://schemas.huawei.com/res/ohos-auto"//声明一个用于传输自定义参数的命名空间
ohos:id="$+id:swipeCaptchaView"//规定控件id
ohos:height="220vp"//控件的高
ohos:width="330vp"//控件的宽
captcha:captchaHeight="30vp"//拼图滑块高
captcha:captchaWidth="30vp"//拼图滑块宽
captcha:matchDeviation="9"/>//验证失败的阈值

③绑定 SwipeCaptchaView 控件

在 MainAbilitySlice.java 的 onStart() 方法中,使用 findComponentById() 方法将 xml 文件中 SwipeCaptchaView 控件与 SwipeCaptchaView 类对象绑定;再调用 setImageId() 方法设置组件的背景图片。

//根据id找到相应的控件
swipeCaptchaView=(SwipeCaptchaView)findComponentById(ResourceTable.Id_swipeCaptchaView);
...
button=(Button)findComponentById(ResourceTable.Id_btn_change);

//设置背景图片
swipeCaptchaView.setImageId(ResourceTable.Media_pic01);

④设置回调处理函数

设置 SwipeCaptchaView 组件的回调处理函数,来提示用户滑动验证结果。

以提示用户验证成功为例:首先重写 matchSuccess() 方法,设置验证成功后的提示信息,然后实例化一个 ToastDialog 提示框对象,使用 setText() 方法设置显示文字为“验证成功!”。

setAlignment() 方法设置提示框的布局位置在整体布局的中央;show() 方法用于显示提示框。

设置验证失败的情况和验证成功同理,只需重写 matchFailed() 方法将文字信息设置为“验证失败!”即可。

//每次滑动结束后会根据判定结果回调
swipeCaptchaView.setOnCaptchaMatchCallback(newSwipeCaptchaView.OnCaptchaMatchCallback(){
@Override
publicvoidmatchSuccess(SwipeCaptchaViewswipeCaptchaView){
newToastDialog(getContext())
.setText("验证成功!")
.setAlignment(LayoutAlignment.CENTER)
.show();
}
});

⑤设置 Button 控件监听事件,重新生成验证区域

绑定 button 对象和 xml 文件中“重新生成验证码”Button控件;为 button 设置监听事件,每次点击按钮,都会调用 createCaptcha() 方法随机生成滑块和原图的位置。

button=(Button)findComponentById(ResourceTable.Id_btn_change);//绑定Button
button.setClickedListener(newComponent.ClickedListener(){//设置监听
@Override
publicvoidonClick(Componentcomponent){
swipeCaptchaView.createCaptcha();//随机生成滑块和原图的位置
...
}
});

Library解析

本部分将要重点介绍的类是图 3 中框出的 2 个类,分别是 DrawHelperUtils 和 SwipeCaptchaView。

它们向开发者提供设置 SwipeCaptcha_ohos2.0 组件相关属性的具体执行方法,其中 DrawHelperUtils 是工具类,SwipeCaptchaView 是具体实现滑块滑动效果的类,本节将分别讲解这两个类的内部逻辑实现。

①DrawHelperUtils 类

Swipeptcha_ohos2.0 升级实现的拼图滑块的原理是在方块的左、右两条竖边中点处分别绘制一个凸半圆或凹半圆(随机),可参考图 4。

DrawHelperUtils 类的 drawPartCircle() 方法具体用于绘制拼图滑块两条竖边上的半圆。

先来解释一下该方法涉及变量和参数的含义:
  • 起点坐标:开始绘制半圆的起点坐标,在图中由A表示,规定为方块竖边的前 1/3 处,由入参传入。

  • 终点坐标:开始绘制半圆的起点坐标,在图中由 C 表示,规定为方块竖边的后 1/3 处,由入参传入。

  • 中点坐标:半圆直径的中点坐标,在图中由 B 表示,由起点 A 和终点 C 的 X、Y 坐标计算得到。

  • r1:半圆半径 = AB 长度 = AC 长度/2 = 1/6 方块竖边长度。

  • gap1:由 r1 乘以贝塞尔曲线(cubicTo() 方法)系数 c 得到,用于确定控制点 D 和 F 的坐标,控制点作用是控制半圆绘制的轨迹。

  • flag:半圆的旋转系数,用来控制凹、凸半圆的绘制。当为 1 时,A、B、C 坐标与变量相加,绘制向外的凸半圆;当为 -1 时,其坐标与变量相减,得到向内的凹半圆。

以竖直绘制一个凸半圆为例,根据 A、B、C 点计算得到上述变量后,调用两次贝塞尔曲线 cubicTo(x1,y1,x2,y2,x3,y3)分别绘制前 1/2 和后 1/2 半圆。

此方法中需要使用到两个控制点,共有 6 个参数,分别表示控制点 1(x1,y1)、控制点 2(x2,y2)和绘制终点(x3,y3)。

如图 4-1,绘制前 1/2 半圆时以起点 A 右侧平行 gap1flag1 距离处作为第一个控制点 D、中点 B 右侧平行 r1 距离的半圆顶点第二个控制点 E、中点 B 作为绘制终点。

绘制后 1/2 半圆同理,以 E 点作为第一个控制点,终点 C 右侧平行 gap1flag1 距离处作为第二个控制点 F、终点 C 作为绘制终点。

其他绘制方向同理,若为从下向上绘制,则将 flag 设为 -1;若绘制凹半圆,则在计算坐标时横坐标反方向计算即可可参考图 4-2。

publicstaticvoiddrawPartCircle(Pointstart,Pointend,Pathpath,booleanouter){
floatc=0.551915024494f;
Pointmiddle=newPoint(start.getPointX()+(end.getPointX()-start.getPointX())/2,start.getPointY()+(end.getPointY()-start.getPointY())/2);//根据起点坐标A和终点坐标C算出中点B坐标
//半径
floatr1=(float)Math.sqrt(Math.pow((middle.getPointX()-start.getPointX()),2)+Math.pow((middle.getPointY()-start.getPointY()),2));
floatgap1=r1*c;//距离gap

if(start.getPointX()==end.getPointX()){//绘制竖直方向
booleantopToBottom=end.getPointY()-start.getPointY()>0;
intflag;//旋转系数
if(topToBottom){//若从上到下绘制
flag=1;//旋转系数设为1
}else{flag=-1;}//若从下到上绘制,设为-1
if(outer){//若为凸半圆,相加
path.cubicTo(start.getPointX()+gap1*flag,start.getPointY(),middle.getPointX()+r1*flag,middle.getPointY()-gap1*flag,middle.getPointX()+r1*flag,middle.getPointY());
path.cubicTo(middle.getPointX()+r1*flag,middle.getPointY()+gap1*flag,end.getPointX()+gap1*flag,end.getPointY(),end.getPointX(),end.getPointY());
}...}//若为凹半圆,则相减
}

②SwipteCaptchaView 类

SwipeCaptchaView 是具体实现滑块滑动效果的类,下文将从初始化滑动条并设置滑动条监听、初始化验证区域背景、设置验证后的动画效果、生成滑动验证区域四个方面具体讲解实现逻辑。

接下来将按类型讲解类中各方法间的调用逻辑,可参考图 4:

①初始化滑动条并设置滑动条监听

在 SwipteCaptchaView 类的构造函数中,调用 init() 方法进行初始化。其中,获取 xml 文件中控件参数即宽、高和系统屏幕宽度;通过 switch-case 判断来获取滑块的宽、高和滑动误差值。

mHeight=getHeight();//获取控件高和款
mWidth=getWidth();//获取系统屏幕宽度
if(mWidth==0){//mWidth=0为设置了match_parent的情况
mWidth=DisplayManager.getInstance().getDefaultDisplay(context).get().getAttributes().width;
}

for(inti=0;i< attrSet.getLength(); i++) {
    Optionalattr=attrSet.getAttr(i);
if(attr.isPresent()){
switch(attr.get().getName()){
case"captchaHeight"://获取滑块高度
mCaptchaHeight=attr.get().getDimensionValue();
break;
case"captchaWidth"://获取滑块宽度
...
case"matchDeviation"://获取滑动误差值
...
}
}
}

实例化 Image 类得到验证区域图片对象,并为其设置图片缩放模式以及位图格式等属性;实例化 Slider 类得到拖动条对象,为其设置宽、高、进度值、进度颜色等属性,以及监听事件。

mImage=newImage(context);//表示验证区域图片
...
mImage.setScaleMode(Image.ScaleMode.CLIP_CENTER);
mImage.setPixelMap(ResourceTable.Media_no_resource);
...
mSlider=newSlider(mLayout.getContext());//实例化Slider类表示拖动条
mSlider.setWidth(mWidth);//设置宽、高
mSlider.setHeight(SLIDER_HEIGHT);
mSlider.setMarginTop(mHeight-SLIDER_HEIGHT);
mSlider.setMinValue(0);//进度最小、最大值、当前进度值、进度颜色
mSlider.setMaxValue(10000);
mSlider.setProgressValue(0)
mSlider.setProgressColor(Color.BLACK);
setSlideListener();//设置拖动条的监听事件
...

在拖动条监听事件 setSlideListener() 方法中,重写 onTouchEnd() 方法,判断滑动结束后滑块位置的误差值是否小于规定误差值。

若小于则验证成功,取消滑块的阴影并设置回调;否则验证失败,直接设置回调。

@Override
publicvoidonTouchEnd(Sliderslider){
if(onCaptchaMatchCallback!=null){
if(Math.abs(mSlider.getProgress()*(mWidth-mCaptchaWidth)/10000-mCaptchaX)< mMatchDeviation) {//滑动结束后滑块位置误差值小于规定误差值验证成功
mCaptchaPaint.setMaskFilter(null);//取消滑块的阴影
slider.setEnabled(false);
onCaptchaMatchCallback.matchSuccess(SwipeCaptchaView.this);//设置验证成功后的回调
mSuccessAnim.start();//播放验证成功动画
}else{//滑动误差值大于规定误差值验证失败
slider.setProgressValue(0);
onCaptchaMatchCallback.matchFailed(SwipeCaptchaView.this);//设置验证失败后的回调
mFailAnim.start();//播放验证失败动画
}
}
}

②初始化滑动验证区域

在通过 Image 类对象调用 setPixelMap() 方法设置完验证图片后,由 initCaptcha() 方法完成验证区域的初始化。 实例化两个 Paint 类分别得到画笔对象和滑块目标区域对象,为其设置画笔抗锯齿和阴影、滑块样式和颜色等属性。

再分别调用 createMatchAnim() 和 createCaptcha() 方法设置验证后的动画效果和生成滑动验证区域。

privatevoidinitCaptcha(){
mRandom=newRandom(System.nanoTime());
//设置画笔
mCaptchaPaint=newPaint();//画笔对象
mCaptchaPaint.setAntiAlias(true);//抗锯齿
mCaptchaPaint.setDither(true);//使位图进行有利的抖动的位掩码标志
mCaptchaPaint.setStyle(Paint.Style.FILL_STYLE);
mCaptchaPaint.setMaskFilter(newMaskFilter(10,MaskFilter.Blur.SOLID));//阴影
//滑块目标区域
mMaskPaint=newPaint();//滑块目标区域对象
mMaskPaint.setAntiAlias(true);
mMaskPaint.setDither(true);
mMaskPaint.setStyle(Paint.Style.FILL_STYLE);//填充样式
mMaskPaint.setColor(newColor(Color.argb(188,0,0,0)));//填充颜色
mMaskPaint.setMaskFilter(newMaskFilter(20,MaskFilter.Blur.INNER));//阴影
mCaptchaPath=newPath();

createMatchAnim();//设置验证后的动画效果
createCaptcha();//生成验证码区域
}

③设置验证后的动画效果

由 createMatchAnim() 方法实现,能够设置验证成功或失败后的动画效果。

验证成功:通过 AnimatorValue 类对象设置动画间隔时间为 500 毫秒;并为其设置当值更新时的监听事件,重写 onUpdate() 方法,设置成功动画中拼图的偏移量。

//成功动画
intwidth=AttrHelper.vp2px(60,mLayout.getContext());
mSuccessAnim=newAnimatorValue();
mSuccessAnim.setDuration(500);//间隔时间为500毫秒
mSuccessAnim.setValueUpdateListener(newAnimatorValue.ValueUpdateListener(){
@Override//设置监听
publicvoidonUpdate(AnimatorValueanimatorValue,floatv){
mSuccessAnimOffset=(int)(v*(mWidth+width));//拼图偏移量
invalidate();
}
});

通过 Paint 类和 Path 类对象分别调用相关函数来完成阴影效果和动画路径的绘制。

mSuccessPaint=newPaint();
mSuccessPaint.setShader(newLinearShader(//设置阴影
newPoint[]{newPoint(0,0),newPoint(width*3/2,mHeight)},
newfloat[]{0,0.5f},
newColor[]{newColor(0x00FFFFFF),newColor(0x66FFFFFF)},
Shader.TileMode.MIRROR_TILEMODE),Paint.ShaderType.LINEAR_SHADER);
mSuccessPath=newPath();//绘制动画路径
mSuccessPath.moveTo(0,0);
mSuccessPath.rLineTo(width,0);
mSuccessPath.rLineTo(width/2,mHeight-SLIDER_HEIGHT);
mSuccessPath.rLineTo(-width,0);
mSuccessPath.close();//关闭

验证失败:与设置验证成功的前半部分流程相似,不同之处是将动画间隔设为 200 毫秒、还要设置画圈次数为 2 次。

在值更新时的监听事件中,需要判断当更新值小于 0.5f 时,将 isDrawMask 置为 false 即不绘制滑块,反之为 true 则绘制。

//设置验证失败动画
mFailAnim=newAnimatorValue();//实例化验证失败的动画对象
mFailAnim.setDuration(200);//设置间隔时间为200毫秒
mFailAnim.setLoopedCount(2);//设置画圈次数为2次
mFailAnim.setValueUpdateListener(newAnimatorValue.ValueUpdateListener(){
@Override
publicvoidonUpdate(AnimatorValueanimatorValue,floatv){
if(v< 0.5f){
isDrawMask=false;//不绘制滑块
}else{isDrawMask=true;}//绘制滑块
invalidate();
}});
}

④生成滑动验证区域

由 createCaptcha() 方法实现。先调用 createCaptchaPath() 方法绘制拼图块的轮廓路径。

其中通过 Random 类的 nextInt() 方法随机生成验证区域坐标,使滑块和原图位置随机变化。

再使用工具类 DrawHelperUtils 的 DrawPartCircle() 方法绘制拼图块左上角、右上角、右下角和左下角的图形。

privatevoidcreateCaptchaPath(){//绘制拼图块轮廓路径path
intgap=mCaptchaWidth/3;//拼图缺口的位置,设置在中间1/3处
mCaptchaX=mRandom.nextInt(mWidth-(mCaptchaWidth*3)-gap)+(mCaptchaWidth*2);//随机生成验证区域左上角的坐标
mCaptchaY=mRandom.nextInt(mHeight-SLIDER_HEIGHT-mCaptchaHeight-gap);
mCaptchaPath.reset();
mCaptchaPath.lineTo(0,0);
//开始绘制图形
mCaptchaPath.moveTo(mCaptchaX,mCaptchaY);//左上角
mCaptchaPath.lineTo(mCaptchaX+gap,mCaptchaY);
drawPartCircle(newPoint(mCaptchaX+gap,mCaptchaY),newPoint(mCaptchaX+gap*2,mCaptchaY),
mCaptchaPath,mRandom.nextBoolean());
...//右上角、右下角和左下角同理
mCaptchaPath.close();//绘制完成后及时关闭
}

接着生成滑动验证区域,前面介绍过,SwipeCaptcha_ohos2.0 版升级实现了验证区域背景图片自适应填充的效果。

其实现原理是先获取位图;根据图片的宽高和控件实际的宽高分别计算出水平方向和竖直方向上的缩放比例,两者中较大的是图片真实的缩放比例。

这是由于上文介绍的 Image 控件将图片缩放模式设为了 CLIP_CENTER,该模式会将图片的短边缩放至合适的大小并对长边进行裁剪。

因此较小的缩放比例代表被裁剪的边,较大的即在填充进控件时的真实缩放比例;接着绘制滑块目标区域的阴影,其不随拖动条的移动而更新。

最后绘制滑块区域,根据拖动条的数值计算画布偏移量,调用 drawPath() 方法绘制边框,获取图片 PixelMapHolder。

根据路径裁剪并将画布缩放至跟图片缩放程度一致,根据比例计算出垂直方向上由于 CLIP_CENTER 裁剪掉的图片的高度以及水平方向上被裁掉的宽度,即可绘制内容。

publicvoidcreateCaptcha(){//生成验证区域
if(mImage.getPixelMap()!=null){
createCaptchaPath();//绘制拼图块轮廓路径Path
...}

PixelMapmCaptchaPixelMap=mImage.getPixelMap();//getPixelMap(mLayout.getContext(),ResourceTable.Media_pic01);
//根据图片的原宽度和控件宽度算出缩放比例
intoriginWidth=mCaptchaPixelMap.getImageInfo().size.width;
intoriginHeight=mCaptchaPixelMap.getImageInfo().size.height;
floatratioWidth=(float)mWidth/originWidth;
floatratioHeight=(float)(mHeight-SLIDER_HEIGHT)/originHeight;
floatratio=Math.max(ratioWidth,ratioHeight);//更大的ratio

mImage.addDrawTask((component,canvas)->{//滑块目标区域阴影的绘制
canvas.drawPath(mCaptchaPath,mMaskPaint);
});
mLayout.addDrawTask((component,canvas)->{//滑块区域的绘制
if(isDrawMask){
canvas.translate(mSlider.getProgress()*(mWidth-mCaptchaWidth)/10000-mCaptchaX,0);//根据拖动条的数值计算画布的偏移量
canvas.drawPath(mCaptchaPath,mCaptchaPaint);//绘制边框
PixelMapHoldermCaptchaPixelMapHolder=newPixelMapHolder(mCaptchaPixelMap);//获取图片的PixelMapHolder
canvas.clipPath(mCaptchaPath,Canvas.ClipOp.INTERSECT);//根据路径裁剪
canvas.scale(ratio,ratio);//画布缩放至跟图片缩放程度一致
if(ratio==ratioWidth){
floatheightErr=(originHeight*ratio-(mHeight-SLIDER_HEIGHT))/2;//根据比例计算出垂直方向上由于CLIP_CENTER裁剪掉的图片的高度
canvas.drawPixelMapHolder(mCaptchaPixelMapHolder,0,-heightErr/ratio,mCaptchaPaint);//绘制内容
}
else{
floatwidthErr=(originWidth*ratio-mWidth)/2;//根据比例计算出水平方向上由于CLIP_CENTER裁剪掉的图片的宽度
canvas.drawPixelMapHolder(mCaptchaPixelMapHolder,-widthErr/ratio,0,mCaptchaPaint);//绘制内容
}
}});
}
责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2642

    浏览量

    69334
  • HarmonyOS
    +关注

    关注

    80

    文章

    2146

    浏览量

    35555

原文标题:鸿蒙滑动拼图验证组件,已开源!

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于开源鸿蒙的视频播放开发样例

    在开源鸿蒙生态建设中,多媒体能力是构建丰富用户体验的核心要素。本开发样例针对视频播放场景,聚焦开源鸿蒙原生媒体框架,通过Video组件实现视频资源加载、播放状态控制及多样
    的头像 发表于 08-19 10:41 1311次阅读
    基于开源<b class='flag-5'>鸿蒙</b>的视频播放开发样例

    【HarmonyOS 5】金融应用开发鸿蒙组件实践

    NEXT(鸿蒙 5.0) 发布,这是中国首个全栈自研操作系统,彻底脱离,流畅度显著提升,标志中国在操作系统领域取得突破性进展
    的头像 发表于 07-11 18:20 744次阅读
    【HarmonyOS 5】金融应用开发<b class='flag-5'>鸿蒙</b><b class='flag-5'>组件</b>实践

    释放潜力:在树莓派上运行系统实现多样应用!

    为什么要在树莓派上运行系统?系统以其庞大的应用生态系统和用户友好的界面而闻名,它能够将树莓派转变为功能强大的设备,能够处理从媒体消费到轻量级计算和物联网应用等各种任务。优势高度
    的头像 发表于 07-05 08:33 894次阅读
    释放潜力:在树莓派上运行<b class='flag-5'>安</b><b class='flag-5'>卓</b>系统<b class='flag-5'>实现</b>多样<b class='flag-5'>化</b>应用!

    【HarmonyOS next】ArkUI-X休闲益智儿童拼图【进阶】

    项目,我们验证了ArkUI-X框架的强大跨端能力。无论是华为的鸿蒙系统,还是iOS平台,都能保持90%以上代码复用率,真正实现了\"一次开发,多端部署\"的理想状态。期待
    发表于 06-28 21:41

    HarmonyOS NEXT应用元服务布局优化长列表使用懒加载与组件复用

    数据如下 可以发现列表滑动时丢帧率明显降低,这是因为,List列表开启了组件复用,不会执行BuildLazyItem这个耗时操作,后续创建新组件节点时,会直接复用缓存区中的节点,这样就大幅节约了
    发表于 06-27 16:08

    如何实现与恩智浦i.MX RT1170的无线投屏与控制

    Scrcpy是一款免费开源的软件,支持将端屏幕投影到其他设备,并支持被投屏设备对的反向控制。基于ADB工具,
    的头像 发表于 06-26 09:53 1934次阅读
    如何<b class='flag-5'>实现</b><b class='flag-5'>安</b><b class='flag-5'>卓</b>与恩智浦i.MX RT1170的无线投屏与控制

    HarmonyOS实战:组件项目搭建

    前言 鸿蒙应用开发已经成为互联网新的风口,开发鸿蒙软件已经成为今年工作的核心目标。在软件开发过程中,对于复杂度较大,功能较多的软件都会采用组件项目架构,那么对于
    的头像 发表于 06-09 14:58 505次阅读
    HarmonyOS实战:<b class='flag-5'>组件</b><b class='flag-5'>化</b>项目搭建

    华为推出首款搭载HarmonyOS 5的鸿蒙电脑

    。作为首个从操作系统内核层面重构的国产电脑,华为此次发布的鸿蒙电脑已顺利通过开源鸿蒙兼容性测评,开机画面显示“Powered by OpenHarmony”标识。鸿蒙电脑的发布标志着开
    的头像 发表于 05-26 09:28 1301次阅读

    国产操作系统加速崛起——鸿蒙电脑补齐鸿蒙生态最重要拼图

    实现重要突破。 “鸿蒙电脑的推出,是鸿蒙操作系统生态版图得以完整的关键一步。”浙江大学传媒与国际文化学院常务副院长方兴东对科技日报记者说,“目前全球只有鸿蒙操作系统可以真正
    的头像 发表于 05-21 11:41 491次阅读

    有人接rk3576的视频硬件解码的实现么?

    ,机顶盒是Android 14,CPU是RK3576,商家说是支持视频硬解,但是没有提供更具体的资料了。 我们是想在这个硬件基础上实现视频硬解,看是否有相关经验的人来接 关于需求可看下面:*附件:6 需求介绍.pdf
    发表于 05-19 09:52

    Get这个秘籍,鸿蒙原生应用页面滑动丝滑无比

    方式,既解决了滑动过程中图片加载不及时导致的卡顿白块,又避免了首页白屏问题,同时降低内存压力。华为与鸿蒙生态中的应用伙伴通力合作,在多个实际应用场景中验证了该方案的可行性,帮助使用imageKnife
    发表于 03-06 14:41

    自制 AirTag,支持/鸿蒙/PC/Home Assistant,无需拥有 iPhone

    苹果的 AirTag 很贵,虽然某强北有平价代替品,但是仍需要苹果设备才能绑定,才能查看位置。不支持/鸿蒙/PC ,也不支持集成到 Home Assistant 中。 AirTag
    发表于 02-25 11:22

    鸿蒙原生页面高性能解决方案上线OpenHarmony社区 助力打造高性能原生应用

    全局自定义组件复用,让原生容器组件组件复用子组件,降低了页面丢帧率和白屏时间。这一方案已在多个头部鸿蒙原生应用中得到使用和
    发表于 01-02 18:00

    AKI跨语言调用库神助攻C/C++代码迁移至HarmonyOS NEXT

    本帖最后由 HarmonyOS开发者社区 于 2025-1-3 15:41 编辑 随着HarmonyOS NEXT的发布,越来越多的应用加速推进鸿蒙。在这一过程中,如何高效迁移原有资产、简化
    发表于 01-02 17:08

    广州大彩讲堂:/linux触摸屏四路CVBS输入实现同时显示!

    广州大彩串口屏/linux触摸屏四路CVBS输入实现同时显示!
    的头像 发表于 12-25 16:49 1131次阅读
    广州大彩讲堂:<b class='flag-5'>安</b><b class='flag-5'>卓</b>/linux触摸屏四路CVBS输入<b class='flag-5'>实现</b>同时显示!