# Azexplosion_ohos **Repository Path**: isrc_ohos/azexplosion_ohos ## Basic Information - **Project Name**: Azexplosion_ohos - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 12 - **Forks**: 2 - **Created**: 2021-03-26 - **Last Updated**: 2024-09-23 ## Categories & Tags **Categories**: harmonyos-animate **Tags**: HarmonyComponent ## README # Azexplosion_ohos **本项目是基于开源项目AZExplosion进行鸿蒙化的移植和开发的,可以通过项目标签以及github地址( https://github.com/Xieyupeng520/AZExplosion )追踪到原安卓项目版本。** 项目名称:Azexplosion_ohos 所属系列:鸿蒙的第三方组件适配移植 功能:实现了点击图片粒子破碎效果,以及动画的各种属性用法。 调用差异:无 开发环境:sdk5,DevEco Studio2.1 beta3 项目发起作者:胡鹏达 邮箱:824128845@qq.com 原项目Doc地址:https://github.com/Xieyupeng520/AZExplosion ##### 项目介绍 编程语言:Java 安装教程 下载AZExplosion的har包explosopn.har(位于output文件夹下)。 启动 DevEco Studio,将下载的har包,导入工程目录“entry->libs”下。 在moudle级别下的build.gradle文件中添加依赖,在dependences标签中增加对libs目录下jar包的引用。 dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) …… } 在导入的har包上点击右键,选择“Add as Library”对包进行引用,选择需要引用的模块,并点击“OK”即引用成功。 在sdk5,DevEco Studio2.1 beta3下项目可直接运行 ##### 使用说明 1.需要用到的主要资源 ```Java 1.1 新建对象 public class Particle { //默认小球宽高 public static final int PART_WH = 5; //粒子圆心x float cx; //粒子圆心y float cy; //粒子半径 float radius; //颜色 int color; //透明度 float alpha; Rect mBound; 1.2新建ExplosionField对象,继承自Component,用于做粒子集的画布,需要重写onDraw()方法 public class ExplosionField extends Component { private static final String TAG = "ExplosionField"; public final float DENSITY = DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getAttributes().densityPixels; public int dp2px(int dp) { return Math.round(dp * DENSITY); } //定义canvas private static final Canvas mCanvas = new Canvas(); //用一个List保存动画集 private ArrayList explosionAnimators; private ClickedListener onClickListener; private boolean endFlag = true; public ExplosionField(Context context) { super(context); init(); } public ExplosionField(Context context, AttrSet attrs) { super(context, attrs); init(); } //初始化 private void init() { explosionAnimators = new ArrayList(); attach2Activity((Ability) getContext()); } 1.3新建ExplosionAnimator,继承自ValueAnimator,用来执行自定义动画。 public class ExplosionAnimator extends AnimatorValue implements AnimatorValue.ValueUpdateListener { //默认时间间隔 public static final int DEFAULT_DURATION = 1500; //粒子 private Particle[][] mParticles; //画笔 private Paint mPaint; //组件 private Component mContainer; private float myvalue =0; //粒子动画 public ExplosionAnimator(Component view, PixelMap bitmap, Rect bound) { mPaint = new Paint(); mContainer = view; //设置默认时间 setDuration(DEFAULT_DURATION); setValueUpdateListener(this); //粒子调用generateParticles方法 mParticles = generateParticles(bitmap, bound); } 1.4先通过view的宽高创建出一个同样大小的空白图,用PixelMap 的静态方法createPixelmap()创建 private PixelMap getPixelMap(int resId) { InputStream drawableInputStream = null; try { drawableInputStream = getResourceManager().getResource(resId); ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions(); sourceOptions.formatHint = "image/png"; ImageSource imageSource = ImageSource.create(drawableInputStream, null); ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions(); //设置格式 decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888; PixelMap pixelMap = imageSource.createPixelmap(decodingOptions); return pixelMap; } catch (Exception e) { e.printStackTrace(); } finally { try{ if (drawableInputStream != null){ drawableInputStream.close(); } }catch (Exception e) { e.printStackTrace(); } } return null; } 1.5把快照分解成若干个粒子,这些粒子的组合能看出来是原图的影子,然后再让粒子动起来形成后面的动画,在Particle类中定义静态方法generateParticle()用来生成新的Particle对象 public static Particle generateParticle(int color, Rect bound, Point point) { //行是高 int row = point.getPointYToInt(); //列是宽 int column = point.getPointXToInt(); //新建粒子 Particle particle = new Particle(); particle.mBound = bound; //粒子颜色 particle.color = color; //粒子透明度 particle.alpha = 1f; //把半径设为宽长 particle.radius = PART_WH; // 圆心坐标 particle.cx = bound.left+ PART_WH * column; particle.cy = bound.top + PART_WH * row; return particle; } 1.6在ExplosionAnimator中通过方法getAnimatedValue()就能够不断得到递增的范围(记做factor)。我们先在Particle写好得到变化因素后,属性要发生的改变。cx左右移动都可以,cy向下移动且距离和view高度有关,radius变小,alpha变得越来越透明。public void advance(float factor) { //移动粒子x坐标 cx = cx + factor * random.nextInt(mBound.getWidth()) * (random.nextFloat() -0.5f); //移动粒子y坐标 cy = cy + factor * random.nextInt(mBound.getHeight() / 2); //半径变小 radius = radius - factor * random.nextInt(2); //透明度也逐渐改变 alpha = (1f - factor) * (1 + random.nextFloat()); } } 1.7在ExplosionField中建立一个“爆炸”方法,只要调用这个方法,传入Component,最后执行animator.start(),Component,就会执行爆炸效果。 public void explode(final Component view) { //获取view在屏幕上的绝对坐标 int[] positions = view.getLocationOnScreen(); //修正因为状态栏导致的错位 positions[1] = positions[1] - 159; Rect rect = view.getComponentPosition(); //使得图片与破碎大小一致 rect.set(rect.left-75,rect.top,rect.right+75,rect.bottom+150); final ExplosionAnimator animator = new ExplosionAnimator(this, createBitmapFromView(view), rect); explosionAnimators.add(animator); 1.8在Activity的最上层盖一层透明的ExplosionField视图,用来显示粒子动画。 private void attach2Activity(Ability activity) { ComponentContainer rootView = (ComponentContainer) activity.findComponentById(ResourceTable.Id_group1).getComponentParent ().getComponentParent(); ComponentContainer.LayoutConfig lp = new ComponentContainer.LayoutConfig( ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT); rootView.addComponent(this, lp); } 1.9调用了addListener()方法,就是把需要实现点击破碎效果的view加上监听器 public void addListener(Component view) { if (view instanceof ComponentContainer) { ComponentContainer viewGroup = (ComponentContainer) view; int count = viewGroup.getChildCount(); for (int i = 0 ; i < count; i++) { addListener(viewGroup.getComponentAt(i)); } } else { view.setClickable(true); view.setClickedListener(getOnClickListener()); } } private ClickedListener getOnClickListener() { if (null == onClickListener) { onClickListener = new ClickedListener() { @Override public void onClick(Component component) { ExplosionField.this.explode(component); } }; } return onClickListener; } } 2.布局及初始化 2.1xml布局 2.2 代码中使用布局并初始化 private PixelMap createBitmapFromView(Component view) { PixelMap.InitializationOptions options = new PixelMap.InitializationOptions(); options.size = new Size(100,100); PixelMap bitmap = PixelMap.create(options); if(view.getName().equals("Id_qq")){ bitmap =getPixelMap(ResourceTable.Media_qq); } if(view.getName().equals("Id_qzone")) bitmap =getPixelMap(ResourceTable.Media_qzone); if(view.getName().equals("Id_vx")) bitmap =getPixelMap(ResourceTable.Media_vx); if(view.getName().equals("Id_wb")) bitmap =getPixelMap(ResourceTable.Media_wb); if(view.getName().equals("Id_tb")) bitmap =getPixelMap(ResourceTable.Media_tb); if(view.getName().equals("Id_baidu_map")) bitmap =getPixelMap(ResourceTable.Media_baidu_map); if(view.getName().equals("Id_gaode_map")) bitmap =getPixelMap(ResourceTable.Media_gaode_map); if(view.getName().equals("Id_qq_music")) bitmap =getPixelMap(ResourceTable.Media_qq_music); return bitmap; } 版本迭代 v0.1.0-alpha 版权和许可信息 azexplosion_ohos经过[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0)授权许可.