@@ -36,7 +33,7 @@ import java.util.List; *
* email : 196425254@qq.com
*/
-public class CircleMenu extends View {
+public class CircleMenu extends ComponentContainer implements Component.DrawTask, Component.EstimateSizeListener, Component.TouchEventListener {
private static final int STATUS_MENU_OPEN = 1;
@@ -70,13 +67,13 @@ public class CircleMenu extends View {
private int mainMenuColor;
- private Drawable openMenuIcon, closeMenuIcon;
+ private PixelMapElement openMenuIcon, closeMenuIcon;
private List
@@ -497,9 +554,9 @@ public class CircleMenu extends View {
*
* @param color 被调整 Alpha 值的颜色
* @param reverse true : 由不透明到透明的顺序调整,否则就逆序
- * @return
+ * @return Color Color
*/
- private int calcAlphaColor(int color, boolean reverse) {
+ private Color calcAlphaColor(int color, boolean reverse) {
int alpha;
if (reverse) { // 由不透明到透明
alpha = (int) (255 * (1.f - fraction));
@@ -508,32 +565,57 @@ public class CircleMenu extends View {
}
if (alpha >= 255) alpha = 255;
if (alpha <= 0) alpha = 0;
- return ColorUtils.setAlphaComponent(color, alpha);
+ if (alpha >= 0 && alpha <= 255) {
+ return new Color(color & 16777215 | alpha << 24);
+ } else {
+ throw new IllegalArgumentException("alpha must be between 0 and 255.");
+ }
}
/**
* 启动打开菜单动画
*/
private void startOpenMenuAnima() {
- ValueAnimator openAnima = ValueAnimator.ofFloat(1.f, 100.f);
+// ofFloat(1.f, 100.f)
+ AnimatorValue openAnima = new AnimatorValue();
openAnima.setDuration(500);
- openAnima.setInterpolator(new OvershootInterpolator());
- openAnima.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ openAnima.setCurveType(Animator.CurveType.OVERSHOOT);
+ openAnima.setStateChangedListener(new Animator.StateChangedListener() {
@Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- fraction = valueAnimator.getAnimatedFraction();
- itemMenuRadius = fraction * partSize;
- itemIconSize = (int) (fraction * iconSize);
- invalidate();
+ public void onStart(Animator animator) {
}
- });
- openAnima.addListener(new AnimatorListenerAdapter() {
+
+ @Override
+ public void onStop(Animator animator) {
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+ }
+
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onEnd(Animator animator) {
status = STATUS_MENU_OPENED;
if (onMenuStatusChangeListener != null)
onMenuStatusChangeListener.onMenuOpened();
}
+
+ @Override
+ public void onPause(Animator animator) {
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+ }
+ });
+ openAnima.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float interpolatedTime) {
+ fraction = interpolatedTime;
+ itemMenuRadius = fraction * partSize;
+ itemIconSize = (int) (fraction * iconSize);
+ invalidate();
+ }
});
openAnima.start();
}
@@ -542,25 +624,46 @@ public class CircleMenu extends View {
* 启动取消动画
*/
private void startCancelMenuAnima() {
- ValueAnimator cancelAnima = ValueAnimator.ofFloat(1.f, 100.f);
+ // ofFloat(1.f, 100.f)
+ AnimatorValue cancelAnima = new AnimatorValue();
cancelAnima.setDuration(500);
- cancelAnima.setInterpolator(new AnticipateInterpolator());
- cancelAnima.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ cancelAnima.setCurveType(Animator.CurveType.ANTICIPATE);
+ cancelAnima.setStateChangedListener(new Animator.StateChangedListener() {
@Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- fraction = valueAnimator.getAnimatedFraction();
- itemMenuRadius = (1 - fraction) * partSize;
- itemIconSize = (int) ((1 - fraction) * iconSize);
- invalidate();
+ public void onStart(Animator animator) {
}
- });
- cancelAnima.addListener(new AnimatorListenerAdapter() {
+
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onStop(Animator animator) {
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+ }
+
+ @Override
+ public void onEnd(Animator animator) {
status = STATUS_MENU_CLOSED;
if (onMenuStatusChangeListener != null)
onMenuStatusChangeListener.onMenuClosed();
}
+
+ @Override
+ public void onPause(Animator animator) {
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+ }
+ });
+ cancelAnima.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float interpolatedTime) {
+ fraction = interpolatedTime;
+ itemMenuRadius = (1 - fraction) * partSize;
+ itemIconSize = (int) ((1 - fraction) * iconSize);
+ invalidate();
+ }
});
cancelAnima.start();
}
@@ -576,62 +679,131 @@ public class CircleMenu extends View {
*/
private void startCloseMeunAnima() {
// 选中菜单项转动一周动画驱动
- ValueAnimator aroundAnima = ValueAnimator.ofFloat(1.f, 100.f);
+ // ofFloat(1.f, 100.f)
+ AnimatorValue aroundAnima = new AnimatorValue();
aroundAnima.setDuration(600);
- aroundAnima.setInterpolator(new AccelerateDecelerateInterpolator());
- aroundAnima.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ aroundAnima.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
+ aroundAnima.setStateChangedListener(new Animator.StateChangedListener() {
+ @Override
+ public void onStart(Animator animator) {
+ }
+
+ @Override
+ public void onStop(Animator animator) {
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+ }
+
+ @Override
+ public void onEnd(Animator animator) {
+ status = STATUS_MENU_CLOSE_CLEAR;
+ }
+
+ @Override
+ public void onPause(Animator animator) {
+ }
+
@Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- fraction = valueAnimator.getAnimatedFraction();
+ public void onResume(Animator animator) {
+ }
+ });
+ aroundAnima.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float interpolatedTime) {
+ fraction = interpolatedTime;
// 中心主菜单图标以两倍速度缩小
float animaFraction = fraction * 2 >= 1 ? 1 : fraction * 2;
itemIconSize = (int) ((1 - animaFraction) * iconSize);
invalidate();
}
});
- aroundAnima.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- status = STATUS_MENU_CLOSE_CLEAR;
- }
- });
+ aroundAnima.start();
// 环状轨迹扩散消失动画驱动
- ValueAnimator spreadAnima = ValueAnimator.ofFloat(1.f, 100.f);
- spreadAnima.setInterpolator(new LinearInterpolator());
- spreadAnima.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ // ofFloat(1.f, 100.f)
+ AnimatorValue spreadAnima = new AnimatorValue();
+ spreadAnima.setDuration(600);
+ spreadAnima.setCurveType(Animator.CurveType.LINEAR);
+ spreadAnima.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
@Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- fraction = valueAnimator.getAnimatedFraction();
+ public void onUpdate(AnimatorValue animatorValue, float interpolatedTime) {
+ fraction = interpolatedTime;
}
});
+
// 主菜单转动动画驱动
- ValueAnimator rotateAnima = ValueAnimator.ofFloat(1.f, 100.f);
- rotateAnima.setInterpolator(new OvershootInterpolator());
- rotateAnima.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ // ofFloat(1.f, 100.f)
+ AnimatorValue rotateAnima = new AnimatorValue();
+ rotateAnima.setCurveType(Animator.CurveType.OVERSHOOT);
+ rotateAnima.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
@Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- rFraction = valueAnimator.getAnimatedFraction();
+ public void onUpdate(AnimatorValue animatorValue, float interpolatedTime) {
+ fraction = interpolatedTime;
itemIconSize = (int) (rFraction * iconSize);
invalidate();
}
});
- AnimatorSet closeAnimaSet = new AnimatorSet();
+
+ AnimatorGroup closeAnimaSet = new AnimatorGroup();
closeAnimaSet.setDuration(500);
- closeAnimaSet.play(spreadAnima).with(rotateAnima);
- closeAnimaSet.addListener(new AnimatorListenerAdapter() {
+ AnimatorGroup.Builder animatorGroupBuilder = closeAnimaSet.build();
+ // 4个动画的顺序为: am1 -> am2/am3 -> am4
+ animatorGroupBuilder.addAnimators(spreadAnima, rotateAnima);
+ closeAnimaSet.setStateChangedListener(new Animator.StateChangedListener() {
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onStart(Animator animator) {
+ System.out.println("zzmzzm-"+"closeanimal");
+ }
+
+ @Override
+ public void onStop(Animator animator) {
+
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+
+ }
+
+ @Override
+ public void onEnd(Animator animator) {
status = STATUS_MENU_CLOSED;
+ System.out.println("zzmzzm-onEnd"+"closeanimalstatus+=="+status);
+
if (onMenuStatusChangeListener != null)
onMenuStatusChangeListener.onMenuClosed();
+ invalidate();
}
- });
- AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.play(aroundAnima).before(closeAnimaSet);
+ @Override
+ public void onPause(Animator animator) {
+
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+
+ }
+ });
+// AnimatorSet closeAnimaSet = new AnimatorSet();
+// closeAnimaSet.setDuration(500);
+// closeAnimaSet.play(spreadAnima).with(rotateAnima);
+// closeAnimaSet.addListener(new AnimatorListenerAdapter() {
+// @Override
+// public void onAnimationEnd(Animator animation) {
+// status = STATUS_MENU_CLOSED;
+// if (onMenuStatusChangeListener != null)
+// onMenuStatusChangeListener.onMenuClosed();
+// }
+// });
+ AnimatorGroup animatorSet = new AnimatorGroup();
+ AnimatorGroup.Builder animatorSetGroupBuilder = animatorSet.build();
+ // 4个动画的顺序为: am1 -> am2/am3 -> am4
+ animatorSetGroupBuilder.addAnimators(aroundAnima).addAnimators(closeAnimaSet);
animatorSet.start();
}
@@ -639,14 +811,14 @@ public class CircleMenu extends View {
* 获取当前点击的是哪一个菜单按钮
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.hitomi.circlemenu;
+
+import com.hitomi.circlemenu.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/entry/src/main/java/com/hitomi/circlemenu/MyApplication.java b/entry/src/main/java/com/hitomi/circlemenu/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..74a924aa1cae6472c5827b0fd98d52e5b7e4701a
--- /dev/null
+++ b/entry/src/main/java/com/hitomi/circlemenu/MyApplication.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.hitomi.circlemenu;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/entry/src/main/java/com/hitomi/circlemenu/slice/MainAbilitySlice.java b/entry/src/main/java/com/hitomi/circlemenu/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd0fd91644e85fc0d83ce9f43bffe9240fcd785e
--- /dev/null
+++ b/entry/src/main/java/com/hitomi/circlemenu/slice/MainAbilitySlice.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.hitomi.circlemenu.slice;
+
+import com.hitomi.circlemenu.ResourceTable;
+import com.hitomi.cmlibrary.CircleMenu;
+import com.hitomi.cmlibrary.OnMenuSelectedListener;
+import com.hitomi.cmlibrary.OnMenuStatusChangeListener;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.utils.Color;
+
+public class MainAbilitySlice extends AbilitySlice {
+ private CircleMenu circleMenu;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ getWindow().setStatusBarColor(Color.getIntColor("#2828FF"));
+ circleMenu = (CircleMenu) findComponentById(ResourceTable.Id_circle_menu);
+ circleMenu.setMainMenu(Color.getIntColor("#CDCDCD"), ResourceTable.Graphic_icon_menu, ResourceTable.Graphic_icon_cancel)
+ .addSubMenu(Color.getIntColor("#258CFF"), ResourceTable.Graphic_icon_home)
+ .addSubMenu(Color.getIntColor("#30A400"), ResourceTable.Graphic_icon_search)
+ .addSubMenu(Color.getIntColor("#FF4B32"), ResourceTable.Graphic_icon_notify)
+ .addSubMenu(Color.getIntColor("#8A39FF"), ResourceTable.Graphic_icon_setting)
+ .addSubMenu(Color.getIntColor("#FF6A00"),ResourceTable.Graphic_icon_gps)
+ .setOnMenuSelectedListener(new OnMenuSelectedListener() {
+
+ @Override
+ public void onMenuSelected(int index) {}
+
+ }).setOnMenuStatusChangeListener(new OnMenuStatusChangeListener() {
+
+ @Override
+ public void onMenuOpened() {}
+
+ @Override
+ public void onMenuClosed() {}
+
+ });
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..c2a6b66cf9bbe3634a9332007717dfd5f2db38bf
--- /dev/null
+++ b/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "entry_MainAbility",
+ "value": "entry_MainAbility"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "mainability_HelloWorld",
+ "value": "Hello World"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_main.xml b/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
*
* 中心菜单下标为0,周围菜单从正上方顺时针计数1~5
*
- * @param x
- * @param y
- * @return
+ * @param x x
+ * @param y y
+ * @return int int
*/
private int clickWhichRectF(float x, float y) {
int which = -1;
- for (RectF rectF : menuRectFList) {
- if (rectF.contains(x, y)) {
+ for (RectFloat rectF : menuRectFList) {
+ if (rectF.isInclude(x, y)) {
which = menuRectFList.indexOf(rectF);
break;
}
@@ -654,12 +826,13 @@ public class CircleMenu extends View {
return which;
}
- private Drawable convertDrawable(int iconRes) {
- return getResources().getDrawable(iconRes);
+ private PixelMapElement convertDrawable(int iconRes) {
+ PixelMapElement pixelMapElement = new PixelMapElement(ColorConverUtils.getPixelMap(getContext(), iconRes));
+ return pixelMapElement;
}
- private Drawable convertBitmap(Bitmap bitmap) {
- return new BitmapDrawable(getResources(), bitmap);
+ private PixelMapElement convertBitmap(PixelMap bitmap) {
+ return new PixelMapElement(bitmap);
}
private void resetMainDrawableBounds() {
@@ -675,7 +848,7 @@ public class CircleMenu extends View {
* @param mainMenuColor 主菜单背景色
* @param openMenuRes 菜单打开图标,Resource 格式
* @param closeMenuRes 菜单关闭图标,Resource 格式
- * @return
+ * @return CircleMenu CircleMenu
*/
public CircleMenu setMainMenu(int mainMenuColor, int openMenuRes, int closeMenuRes) {
openMenuIcon = convertDrawable(openMenuRes);
@@ -690,9 +863,9 @@ public class CircleMenu extends View {
* @param mainMenuColor 主菜单背景色
* @param openMenuBitmap 菜单打开图标,Bitmap 格式
* @param closeMenuBitmap 菜单关闭图标,Bitmap 格式
- * @return
+ * @return CircleMenu CircleMenu
*/
- public CircleMenu setMainMenu(int mainMenuColor, Bitmap openMenuBitmap, Bitmap closeMenuBitmap) {
+ public CircleMenu setMainMenu(int mainMenuColor, PixelMap openMenuBitmap, PixelMap closeMenuBitmap) {
openMenuIcon = convertBitmap(openMenuBitmap);
closeMenuIcon = convertBitmap(closeMenuBitmap);
this.mainMenuColor = mainMenuColor;
@@ -705,9 +878,9 @@ public class CircleMenu extends View {
* @param mainMenuColor 主菜单背景色
* @param openMenuDrawable 菜单打开图标,Drawable 格式
* @param closeMenuDrawable 菜单关闭图标,Drawable 格式
- * @return
+ * @return CircleMenu CircleMenu
*/
- public CircleMenu setMainMenu(int mainMenuColor, Drawable openMenuDrawable, Drawable closeMenuDrawable) {
+ public CircleMenu setMainMenu(int mainMenuColor, PixelMapElement openMenuDrawable, PixelMapElement closeMenuDrawable) {
openMenuIcon = openMenuDrawable;
closeMenuIcon = closeMenuDrawable;
this.mainMenuColor = mainMenuColor;
@@ -719,7 +892,7 @@ public class CircleMenu extends View {
*
* @param menuColor 子菜单的背景色
* @param menuRes 子菜单图标,Resource 格式
- * @return
+ * @return CircleMenu CircleMenu
*/
public CircleMenu addSubMenu(int menuColor, int menuRes) {
if (subMenuColorList.size() < MAX_SUBMENU_NUM && subMenuDrawableList.size() < MAX_SUBMENU_NUM) {
@@ -735,9 +908,9 @@ public class CircleMenu extends View {
*
* @param menuColor 子菜单的背景色
* @param menuBitmap 子菜单图标,Bitmap 格式
- * @return
+ * @return CircleMenu CircleMenu
*/
- public CircleMenu addSubMenu(int menuColor, Bitmap menuBitmap) {
+ public CircleMenu addSubMenu(int menuColor, PixelMap menuBitmap) {
if (subMenuColorList.size() < MAX_SUBMENU_NUM && subMenuDrawableList.size() < MAX_SUBMENU_NUM) {
subMenuColorList.add(menuColor);
subMenuDrawableList.add(convertBitmap(menuBitmap));
@@ -751,9 +924,9 @@ public class CircleMenu extends View {
*
* @param menuColor 子菜单的背景色
* @param menuDrawable 子菜单图标,Drawable 格式
- * @return
+ * @return CircleMenu CircleMenu
*/
- public CircleMenu addSubMenu(int menuColor, Drawable menuDrawable) {
+ public CircleMenu addSubMenu(int menuColor, PixelMapElement menuDrawable) {
if (subMenuColorList.size() < MAX_SUBMENU_NUM && subMenuDrawableList.size() < MAX_SUBMENU_NUM) {
subMenuColorList.add(menuColor);
subMenuDrawableList.add(menuDrawable);
@@ -788,7 +961,7 @@ public class CircleMenu extends View {
* 菜单是否关闭
* Returns whether the menu is alread open
*
- * @return
+ * @return boolean boolean
*/
public boolean isOpened() {
return status == STATUS_MENU_OPENED;
@@ -805,7 +978,9 @@ public class CircleMenu extends View {
}
private int dip2px(float dpValue) {
- final float scale = getContext().getResources().getDisplayMetrics().density;
+ final float scale = DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getRealAttributes().densityPixels;
return (int) (dpValue * scale + 0.5f);
}
+
+
}
diff --git a/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/ColorConverUtils.java b/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/ColorConverUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a3b258848ffbe2a483a2b115c09ca6618a29445
--- /dev/null
+++ b/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/ColorConverUtils.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hitomi.cmlibrary.util;
+
+import ohos.app.Context;
+import ohos.global.resource.NotExistException;
+import ohos.media.image.ImageSource;
+import ohos.media.image.PixelMap;
+import ohos.media.image.common.PixelFormat;
+import ohos.media.image.common.Rect;
+import ohos.media.image.common.Size;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 颜色转换工具类
+ *
+ * @since 2021-04-16
+ */
+public final class ColorConverUtils {
+ private static final int ADJUSTCOLOR = 0x00ffffff;
+ private static final int ONE = -1;
+ private static final int SECOND = 2;
+ private static final int THIRD = 3;
+ private static final int FOUR = 4;
+ private static final int NUMBER8 = 8;
+ private static final int NUMBER16 = 16;
+ private static final int ADJUST = 24;
+ private static final int SIXTEN = 60;
+ private static final int ONWSECOND = 120;
+ private static final int SECONDFOUR = 240;
+ private static final int ALPHAINT = 255;
+ private static final int THIRDSIX = 360;
+
+ /**
+ * 构造函数
+ */
+ protected ColorConverUtils() {
+ }
+
+ /**
+ * 透明度数值
+ *
+ * @param alpha alpha
+ * @return 透明度数值
+ */
+ public static int alphaValueAsInt(float alpha) {
+ return Math.round(alpha * ALPHAINT);
+ }
+
+ /**
+ * 透明度调整
+ *
+ * @param alpha alpha
+ * @param color color
+ * @return 透明度数值
+ */
+ public static int adjustAlpha(float alpha, int color) {
+ return alphaValueAsInt(alpha) << ADJUST | (ADJUSTCOLOR & color);
+ }
+
+
+
+ /**
+ * rgb转hsv
+ *
+ * @param rr rr
+ * @param gg gg
+ * @param bb bb
+ * @return rgb转hsv
+ */
+ public static double[] rgbToHsv(double rr, double gg, double bb) {
+ double hh;
+ double ss;
+ double vv;
+ double min;
+ double max;
+ min = Math.min(Math.min(rr, gg), bb);
+ max = Math.max(Math.max(rr, gg), bb);
+ double delta;
+ vv = max;
+ delta = max - min;
+ if (max != 0) {
+ ss = delta / max;
+ } else {
+ ss = 0;
+ hh = ONE;
+ return new double[]{hh, ss, vv};
+ }
+
+ // H
+ if (rr == max) {
+ hh = (gg - bb) / delta; // between yellow & magenta
+ } else if (gg == max) {
+ hh = SECOND + (bb - rr) / delta; // between cyan & yellow
+ } else {
+ hh = FOUR + (rr - gg) / delta; // between magenta & cyan
+ }
+ hh *= SIXTEN; // degrees
+ if (hh < 0) {
+ hh += THIRDSIX;
+ }
+ return new double[]{hh, ss, vv};
+ }
+
+ /**
+ * 颜色id转rgb
+ *
+ * @param color color
+ * @return 颜色id转rgb
+ */
+ public static int[] colorToRgb(int color) {
+ // color id 转RGB
+ int red = (color & Constant.DEFAULT) >> NUMBER16;
+ int green = (color & Constant.DEFAULT2) >> NUMBER8;
+ int blue = color & Constant.DEFAULT3;
+ return new int[]{red, green, blue};
+ }
+
+ /**
+ * hsv格式颜色转rgb格式
+ *
+ * @param hsb hsb
+ * @return hsv格式颜色转rgb格式
+ */
+ public static float[] hsb2rgb(float[] hsb) {
+ float[] rgb = new float[THIRD];
+
+ // 先令饱和度和亮度为100%,调节色相h
+ for (int offset = SECONDFOUR, inum = 0; inum < THIRD; inum++, offset -= ONWSECOND) {
+ // 算出色相h的值和三个区域中心点(即0°,120°和240°)相差多少,然后根据坐标图按分段函数算出rgb。
+ // 但因为色环展开后,红色区域的中心点是0°同时也是360°,不好算,索性将三个区域的中心点都向右平移到240°再计算比较方便
+ float diff = Math.abs(((int)hsb[0] + offset) % THIRDSIX - SECONDFOUR);
+
+ // 如果相差小于60°则为255
+ if (diff <= SIXTEN) {
+ rgb[inum] = ALPHAINT;
+ }
+
+ // 如果相差在60°和120°之间,
+ else if (diff > SIXTEN && diff < ONWSECOND) {
+ rgb[inum] = NumCalcUtil.multiply((NumCalcUtil.subtract(1f , (NumCalcUtil.subtract(diff , SIXTEN)) / SIXTEN)), ALPHAINT);
+ }
+
+ // 如果相差大于120°则为0
+ else {
+ rgb[inum] = 0;
+ }
+ }
+
+ // 在调节饱和度s
+ for (int ii = 0; ii < THIRD; ii++) {
+ rgb[ii] = NumCalcUtil.add(rgb[ii] , NumCalcUtil.multiply((NumCalcUtil.subtract(ALPHAINT , rgb[ii]))
+ , (NumCalcUtil.subtract(1f , hsb[1]))));
+ }
+
+ // 最后调节亮度b
+ for (int ii = 0; ii < THIRD; ii++) {
+ rgb[ii] *= hsb[SECOND];
+ }
+ return rgb;
+ }
+
+
+
+ /**
+ * 通过资源ID获取位图对象
+ *
+ * @param context
+ * @param resId
+ * @return PixelMap
+ */
+ public static PixelMap getPixelMap(Context context, int resId) {
+ return getPixelMap(context, resId, 0, 0);
+ }
+
+ /**
+ * 通过资源ID获取位图对象
+ *
+ * @param context
+ * @param resId
+ * @param width
+ * @param height
+ * @return PixelMap
+ */
+ public static PixelMap getPixelMap(Context context, int resId, int width, int height) {
+ InputStream drawableInputStream = null;
+ try {
+ drawableInputStream = context.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.desiredSize = new Size(width, height);
+ decodingOptions.desiredRegion = new Rect(0, 0, 0, 0);
+ decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
+ PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
+ return pixelMap;
+ } catch (IOException | NotExistException e) {
+ e.fillInStackTrace();
+ } finally {
+ try {
+ if (drawableInputStream != null) {
+ drawableInputStream.close();
+ }
+ } catch (IOException e) {
+ e.fillInStackTrace();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/Constant.java b/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/Constant.java
new file mode 100644
index 0000000000000000000000000000000000000000..f045c5b891b349be2b2e620b40664bf43c9d44aa
--- /dev/null
+++ b/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/Constant.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hitomi.cmlibrary.util;
+
+/**
+ * 常量工具类
+ *
+ * @since 2021-04-16
+ */
+public final class Constant {
+ /**
+ * SECOND
+ */
+ public static final int SECOND = 2;
+ /**
+ * THIRD
+ */
+ public static final int THIRD = 3;
+ /**
+ * STROKE_RATIO
+ */
+ public static final float STROKE_RATIO = 1.5f;
+ /**
+ * SECONDF
+ */
+ public static final float SECONDF = 2f;
+ /**
+ * SECONDFIVERF
+ */
+ public static final float SECONDFIVERF = 2.3f;
+ /**
+ * SECONDFIVERF
+ */
+ public static final float SECONDFIVERF1080 = 2.1f;
+ /**
+ * SECONDNORMAL
+ */
+ public static final float SECONDNORMAL = 2.45f;
+ /**
+ * SECONDNORMAL
+ */
+ public static final float SECONDNORMAL1080 = 2.25f;
+ /**
+ * ONESECONDF
+ */
+ public static final float ONESECONDF = 1.2f;
+ /**
+ * ONEEAT
+ */
+ public static final int ONEEAT = 180;
+ /**
+ * numner 1080
+ */
+ public static final int ONEZOREEATER = 1080;
+ /**
+ * FIVEZORE
+ */
+ public static final int FIVEZORE = 50;
+ /**
+ * EAT
+ */
+ public static final int EAT = 8;
+ /**
+ * TEN
+ */
+ public static final int TEN = 10;
+ /**
+ * NUMBER255F
+ */
+ public static final float NUMBER255F = 255.0f;
+ /**
+ * NUMBER65536
+ */
+ public static final int NUMBER65536 = -65536;
+ /**
+ * TENF
+ */
+ public static final float TENF = 10.0f;
+ /**
+ * ONESIX
+ */
+ public static final int ONESIX = 16;
+ /**
+ * DEFAULT
+ */
+ public static final int DEFAULT = 0xff0000;
+ /**
+ * DEFAULT2
+ */
+ public static final int DEFAULT2 = 0x00ff00;
+ /**
+ * DEFAULT3
+ */
+ public static final int DEFAULT3 = 0x0000ff;
+ /**
+ * red
+ */
+ public static final int DEFAULTRED = 0xFFFF0000;
+ /**
+ * GROSE
+ */
+ public static final int DEFAULTGRESS = 0xFF00FF00;
+ /**
+ * blue
+ */
+ public static final int DEFAULTBLUE = 0xFF0000FF;
+
+ private Constant() {
+ }
+}
diff --git a/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/NumCalcUtil.java b/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/NumCalcUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..886f8a9c2b9954228f2f1de0c67fb14344bd1e67
--- /dev/null
+++ b/cmlibrary/src/main/java/com/hitomi/cmlibrary/util/NumCalcUtil.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hitomi.cmlibrary.util;
+
+import java.math.BigDecimal;
+
+/**
+ * 浮点数计算工具类
+ *
+ * @since 2021-05-17
+ */
+public class NumCalcUtil {
+ private NumCalcUtil() {
+ }
+ /**
+ * 加法
+ *
+ * @param num1
+ * @param num2
+ * @return 结果
+ */
+ public static float add(float num1, float num2) {
+ return new BigDecimal(num1).add(new BigDecimal(num2)).floatValue();
+ }
+
+ /**
+ * 减法
+ *
+ * @param num1
+ * @param num2
+ * @return 结果
+ */
+ public static float subtract(float num1, float num2) {
+ return new BigDecimal(num1).subtract(new BigDecimal(num2)).floatValue();
+ }
+
+ /**
+ * 除法
+ *
+ * @param num1
+ * @param num2
+ * @return 结果
+ */
+ public static float divide(float num1, float num2) {
+ return new BigDecimal(num1).divide(new BigDecimal(num2)).floatValue();
+ }
+
+ /**
+ * 乘法
+ *
+ * @param num1
+ * @param num2
+ * @return 结果
+ */
+ public static float multiply(float num1, float num2) {
+ return new BigDecimal(num1).multiply(new BigDecimal(num2)).floatValue();
+ }
+}
diff --git a/cmlibrary/src/main/res/values/strings.xml b/cmlibrary/src/main/res/values/strings.xml
deleted file mode 100644
index d7dda5264d1b44700813e44c7a680dc0884465fa..0000000000000000000000000000000000000000
--- a/cmlibrary/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-