diff --git a/UI/CustomComponent/README_en.md b/UI/CustomComponent/README_en.md new file mode 100644 index 0000000000000000000000000000000000000000..86f46ecfc2d6bbb678611fc5e4c79f643c4cc128 --- /dev/null +++ b/UI/CustomComponent/README_en.md @@ -0,0 +1,16 @@ +# CustomComponent + +##### Introduction + +You can use the Java UI framework to customize components, add custom draw tasks, and define component attributes and event responses. This sample shows how to customize components. + +##### Usage + +On the application home screen, click the custom component **ColorChangingRing**. A yellow ring is displayed. You can click the ring to change its color. + +On the application home screen, click the custom component **RingProgressBar**. A round progress controller is displayed. You can click the controller to change the progress. + +##### Constraints + +This sample can only be run on standard-system devices. + diff --git a/UI/CustomComponent/README_zh.md b/UI/CustomComponent/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..857d5f24f943e73807d5ef217e1b7ba9ab671286 --- /dev/null +++ b/UI/CustomComponent/README_zh.md @@ -0,0 +1,16 @@ +# 自定义组件 + +##### 简介 + +本示例展示了自定义组件的使用方法,在Java UI框架中提供了更加强大的能力,可以自定义组件,添加自定义绘制任务,并定义组件的属性和事件响应。 + +##### 使用说明 + +进入应用主界面后,点击自定义组件:可变色圆环,跳转页面,出现黄色圆环,点击圆环改变其颜色; + +点击自定义组件:环形进度条,跳转页面,出现环形进度控制器,点击环形可改变其进度。 + +##### 约束和限制 + +本示例支持在标准系统上运行。 + diff --git a/UI/CustomComponent/build.gradle b/UI/CustomComponent/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..e76a14f743baa5377849b43abf29dd0fe29b6478 --- /dev/null +++ b/UI/CustomComponent/build.gradle @@ -0,0 +1,34 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 4 + } +} +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } + dependencies { + classpath 'com.huawei.ohos:hap:2.4.4.2' + } +} +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } +} \ No newline at end of file diff --git a/UI/CustomComponent/entry/build.gradle b/UI/CustomComponent/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..1324a93eda46cb945cc94de68b1cb0d1bcca10d1 --- /dev/null +++ b/UI/CustomComponent/entry/build.gradle @@ -0,0 +1,18 @@ +apply plugin: 'com.huawei.ohos.hap' +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 4 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) +} diff --git a/UI/CustomComponent/entry/src/main/config.json b/UI/CustomComponent/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..4bafcccd1889f6372c0acb5f3c5aa67760b54523 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/config.json @@ -0,0 +1,44 @@ +{ + "app": { + "bundleName": "ohos.samples.customcomponent", + "version": { + "code": 1000000, + "name": "1.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "ohos.samples.customcomponent", + "name": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree":false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "portrait", + "name": ".MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:app_name", + "type": "page", + "launchType": "standard" + } + ] + } +} \ No newline at end of file diff --git a/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/MainAbility.java b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/MainAbility.java new file mode 100644 index 0000000000000000000000000000000000000000..670c9db5dc0c028bfd52ad91430306342485d2f6 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/MainAbility.java @@ -0,0 +1,33 @@ +/* + * 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 ohos.samples.customcomponent; + +import ohos.aafwk.ability.Ability; +import ohos.aafwk.content.Intent; +import ohos.samples.customcomponent.slice.MainAbilitySlice; + +/** + * MainAbility + * + * @since 2021-05-08 + */ +public class MainAbility extends Ability { + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setMainRoute(MainAbilitySlice.class.getName()); + } +} diff --git a/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/modle/CustomComponent.java b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/modle/CustomComponent.java new file mode 100644 index 0000000000000000000000000000000000000000..03ef3e91156469ebf3e198b957e4ddb838b333e0 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/modle/CustomComponent.java @@ -0,0 +1,101 @@ +/* + * 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 ohos.samples.customcomponent.modle; + +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.render.Canvas; +import ohos.agp.render.Paint; +import ohos.agp.utils.Color; +import ohos.app.Context; +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; +import ohos.multimodalinput.event.TouchEvent; + +/** + * CustomComponent + * + * @since 2021-05-08 + */ +public class CustomComponent extends Component implements Component.EstimateSizeListener, Component.DrawTask, + Component.TouchEventListener { + private static final String TAG = CustomComponent.class.getSimpleName(); + + private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG); + + private static final float CIRCLE_STROKE_WIDTH = 100f; + + private static final float Y = 500; + + private static final float RADIUS = 300; + + private float pointX; + + private Paint circlePaint; + + private boolean isDiscoloration = false; + + /** + * customcomponent + * + * @param context Indicates the Context + * @param attrSet attrset + */ + public CustomComponent(Context context, AttrSet attrSet) { + super(context, attrSet); + setEstimateSizeListener(this); + setTouchEventListener(this); + initPaint(); + addDrawTask(this); + } + + @Override + public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) { + int width = Component.EstimateSpec.getSize(widthEstimateConfig); + int height = Component.EstimateSpec.getSize(heightEstimateConfig); + setEstimatedSize(Component.EstimateSpec.getChildSizeWithMode(width, height, EstimateSpec.NOT_EXCEED), + Component.EstimateSpec.getChildSizeWithMode(width, height, EstimateSpec.NOT_EXCEED)); + pointX = width; + return true; + } + + private void initPaint() { + circlePaint = new Paint(); + circlePaint.setColor(Color.YELLOW); + circlePaint.setStrokeWidth(CIRCLE_STROKE_WIDTH); + circlePaint.setStyle(Paint.Style.STROKE_STYLE); + } + + @Override + public void onDraw(Component component, Canvas canvas) { + canvas.drawCircle(pointX / 2, Y, RADIUS, circlePaint); + } + + @Override + public boolean onTouchEvent(Component component, TouchEvent touchEvent) { + HiLog.info(LABEL_LOG, "onTouchEvent"); + if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN) { + if (!isDiscoloration) { + circlePaint.setColor(Color.GREEN); + } else { + circlePaint.setColor(Color.YELLOW); + } + invalidate(); + isDiscoloration = !isDiscoloration; + } + return false; + } +} diff --git a/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/modle/CustomControlBar.java b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/modle/CustomControlBar.java new file mode 100644 index 0000000000000000000000000000000000000000..ea2de8980f88c6dfc698bf92e92762189b3999c9 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/modle/CustomControlBar.java @@ -0,0 +1,211 @@ +/* + * 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 ohos.samples.customcomponent.modle; + +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.render.Arc; +import ohos.agp.render.Canvas; +import ohos.agp.render.Paint; +import ohos.agp.render.PixelMapHolder; +import ohos.agp.utils.Color; +import ohos.agp.utils.Point; +import ohos.agp.utils.RectFloat; +import ohos.app.Context; +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; +import ohos.media.image.PixelMap; +import ohos.media.image.common.Size; +import ohos.multimodalinput.event.MmiPoint; +import ohos.multimodalinput.event.TouchEvent; +import ohos.samples.customcomponent.ResourceTable; +import ohos.samples.customcomponent.utils.Util; + +/** + * CustomControlBar + * + * @since 2021-05-08 + */ +public class CustomControlBar extends Component implements Component.DrawTask, Component.EstimateSizeListener, + Component.TouchEventListener { + private static final String TAG = CustomComponent.class.getSimpleName(); + + private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG); + + private static final float CIRCLE_ANGLE = 360.0f; + + private static final int DEF_UNFILL_COLOR = 0xFF808080; + + private static final int DEF_FILL_COLOR = 0xFF1E90FF; + + private static final int COUNT = 10; + + private static final int SPLIT_SIZE = 15; + + private static final int CIRCLE_WIDTH = 60; + + private static final int MARGIN = 50; + + private static final int TWO = 2; + + private static final int ANGLE = 90; + + private static final double ROUNDING = 0.4; + + private static final double NUM_TWO = 2.0; + + private static final float NUM_ONE = 1.0f; + + private Color unFillColor; + + private Color fillColor; + + private final Paint paint; + + private int currentCount; + + private RectFloat centerRectFloat; + + private PixelMap image; + + private Point centerPoint; + + /** + * customcontrolbar + * + * @param context Indicates the Context + * @param attrSet attrset + */ + public CustomControlBar(Context context, AttrSet attrSet) { + super(context, attrSet); + paint = new Paint(); + initData(); + setEstimateSizeListener(this); + setTouchEventListener(this); + addDrawTask(this); + } + + private void initData() { + unFillColor = new Color(DEF_UNFILL_COLOR); + fillColor = new Color(DEF_FILL_COLOR); + currentCount = TWO; + centerRectFloat = new RectFloat(); + image = Util.createPixelMapByResId(ResourceTable.Media_icon, getContext()).get(); + } + + @Override + public void onDraw(Component component, Canvas canvas) { + HiLog.info(LABEL_LOG, "onDraw"); + paint.setAntiAlias(true); + paint.setStrokeWidth(CIRCLE_WIDTH); + paint.setStrokeCap(Paint.StrokeCap.ROUND_CAP); + paint.setStyle(Paint.Style.STROKE_STYLE); + + int width = getWidth(); + int center = width / TWO; + centerPoint = new Point(center, center); + int radius = center - CIRCLE_WIDTH / TWO - MARGIN; + drawCount(canvas, center, radius); + + int inRadius = center - CIRCLE_WIDTH; + double length = inRadius - Math.sqrt(TWO) * NUM_ONE / TWO * inRadius; + centerRectFloat.left = (float) (length + CIRCLE_WIDTH); + centerRectFloat.top = (float) (length + CIRCLE_WIDTH); + centerRectFloat.bottom = (float) (centerRectFloat.left + Math.sqrt(TWO) * inRadius); + centerRectFloat.right = (float) (centerRectFloat.left + Math.sqrt(TWO) * inRadius); + + Size imageSize = image.getImageInfo().size; + if (imageSize.width < Math.sqrt(TWO) * inRadius) { + centerRectFloat.left = + (float) (centerRectFloat.left + Math.sqrt(TWO) * inRadius * NUM_ONE / TWO + - imageSize.width * NUM_ONE / TWO); + centerRectFloat.top = + (float) (centerRectFloat.top + Math.sqrt(TWO) * inRadius * NUM_ONE / TWO + - imageSize.height * NUM_ONE / TWO); + centerRectFloat.right = centerRectFloat.left + imageSize.width; + centerRectFloat.bottom = centerRectFloat.top + imageSize.height; + } + canvas.drawPixelMapHolderRect(new PixelMapHolder(image), centerRectFloat, paint); + } + + private void drawCount(Canvas canvas, int center, int radius) { + float itemSize = (CIRCLE_ANGLE - COUNT * SPLIT_SIZE) / COUNT; + + RectFloat oval = new RectFloat(center - radius, center - radius, center + radius, + center + radius); + + paint.setColor(unFillColor); + for (int i = 0; i < COUNT; i++) { + Arc arc = new Arc((i * (itemSize + SPLIT_SIZE)) - ANGLE, itemSize, false); + canvas.drawArc(oval, arc, paint); + } + + paint.setColor(fillColor); + for (int i = 0; i < currentCount; i++) { + Arc arc = new Arc((i * (itemSize + SPLIT_SIZE)) - ANGLE, itemSize, false); + canvas.drawArc(oval, arc, paint); + } + } + + @Override + public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) { + int width = Component.EstimateSpec.getSize(widthEstimateConfig); + int height = Component.EstimateSpec.getSize(heightEstimateConfig); + setEstimatedSize( + Component.EstimateSpec.getChildSizeWithMode(width, height, Component.EstimateSpec.PRECISE), + Component.EstimateSpec.getChildSizeWithMode(width, height, Component.EstimateSpec.PRECISE) + ); + return true; + } + + @Override + public boolean onTouchEvent(Component component, TouchEvent touchEvent) { + switch (touchEvent.getAction()) { + case TouchEvent.PRIMARY_POINT_DOWN: + case TouchEvent.POINT_MOVE: { + MmiPoint absPoint = touchEvent.getPointerPosition(touchEvent.getIndex()); + Point point = + new Point(absPoint.getX() - getContentPositionX(), absPoint.getY() - getContentPositionY()); + double angle = calcRotationAngleInDegrees(centerPoint, point) * TWO; + if (angle > CIRCLE_ANGLE) { + angle -= CIRCLE_ANGLE; + } + double number = angle / (CIRCLE_ANGLE / COUNT); + if ((number - (int) number) > ROUNDING) { + currentCount = (int) number + 1; + } else { + currentCount = (int) number; + } + invalidate(); + break; + } + default: + break; + } + return false; + } + + private double calcRotationAngleInDegrees(Point centerPt, Point targetPt) { + double theta = Math.atan2(targetPt.getPointYToInt() + - centerPt.getPointYToInt(), targetPt.getPointXToInt() - centerPt.getPointXToInt()); + theta += Math.PI / NUM_TWO; + double angle = Math.toDegrees(theta); + if (angle < 0) { + angle += CIRCLE_ANGLE; + } + return angle; + } +} diff --git a/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/AnnulusAbilitySlice.java b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/AnnulusAbilitySlice.java new file mode 100644 index 0000000000000000000000000000000000000000..b7f9499baeb97658837a2181181f287532663093 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/AnnulusAbilitySlice.java @@ -0,0 +1,36 @@ +/* + * 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 ohos.samples.customcomponent.slice; + +import ohos.aafwk.ability.AbilitySlice; +import ohos.aafwk.content.Intent; +import ohos.samples.customcomponent.ResourceTable; +import ohos.samples.customcomponent.modle.CustomComponent; + +/** + * AnnlusAbilitySlice + * + * @since 2021-05-08 + */ +public class AnnulusAbilitySlice extends AbilitySlice { + private CustomComponent component; + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + setUIContent(ResourceTable.Layout_annulus_main_ability); + } +} diff --git a/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/ControllerAbilitySlice.java b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/ControllerAbilitySlice.java new file mode 100644 index 0000000000000000000000000000000000000000..6be09b2bf0475946b635e6a6ebca9eb42cbf4330 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/ControllerAbilitySlice.java @@ -0,0 +1,33 @@ +/* + * 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 ohos.samples.customcomponent.slice; + +import ohos.aafwk.ability.AbilitySlice; +import ohos.aafwk.content.Intent; +import ohos.samples.customcomponent.ResourceTable; + +/** + * ControllerAbilitySlice + * + * @since 2021-05-08 + */ +public class ControllerAbilitySlice extends AbilitySlice { + @Override + public void onStart(Intent intent) { + super.onStart(intent); + setUIContent(ResourceTable.Layout_controller_main_ability); + } +} diff --git a/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/MainAbilitySlice.java b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/MainAbilitySlice.java new file mode 100644 index 0000000000000000000000000000000000000000..15a728f38af60effb06587d6be54389dca8ed234 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/slice/MainAbilitySlice.java @@ -0,0 +1,48 @@ +/* + * 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 ohos.samples.customcomponent.slice; + +import ohos.aafwk.ability.AbilitySlice; +import ohos.aafwk.content.Intent; +import ohos.agp.components.Component; +import ohos.samples.customcomponent.ResourceTable; + +/** + * MainAbilitySlice + * + * @since 2021-05-08 + */ +public class MainAbilitySlice extends AbilitySlice { + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setUIContent(ResourceTable.Layout_main_ability_slice); + Component annulusButton = findComponentById(ResourceTable.Id_annulus_button); + Component controllersButton = findComponentById(ResourceTable.Id_controllers_button); + annulusButton.setClickedListener(listener -> present(new AnnulusAbilitySlice(), new Intent())); + controllersButton.setClickedListener(listener -> present(new ControllerAbilitySlice(), new Intent())); + } + + @Override + public void onActive() { + super.onActive(); + } + + @Override + public void onForeground(Intent intent) { + super.onForeground(intent); + } +} diff --git a/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/utils/Util.java b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/utils/Util.java new file mode 100644 index 0000000000000000000000000000000000000000..337cc23ec0f0eac30ca78799de05a8dbcf73eb2d --- /dev/null +++ b/UI/CustomComponent/entry/src/main/java/ohos/samples/customcomponent/utils/Util.java @@ -0,0 +1,103 @@ +/* + * 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 ohos.samples.customcomponent.utils; + +import ohos.app.Context; +import ohos.global.resource.NotExistException; +import ohos.global.resource.Resource; +import ohos.global.resource.ResourceManager; +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; +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.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Optional; + +/** + * Util Tools + * + * @since 2021-05-08 + */ +public class Util { + private static final HiLogLabel TAG = new HiLogLabel(3, 0xD001100, "Utils"); + + private Util() { + } + + private static byte[] readResource(Resource resource) { + final int bufferSize = 1024; + final int ioEnd = -1; + byte[] byteArray; + byte[] buffer = new byte[bufferSize]; + try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { + while (true) { + int readLen = resource.read(buffer, 0, bufferSize); + if (readLen == ioEnd) { + HiLog.error(TAG, "readResource finish"); + byteArray = output.toByteArray(); + break; + } + output.write(buffer, 0, readLen); + } + } catch (IOException e) { + HiLog.debug(TAG, "readResource failed" + e.getLocalizedMessage()); + return new byte[0]; + } + return byteArray; + } + + /** + * Creates is {@code PixelMap} object based on the image resource ID. + * This method only loads local image resources. If the image file does not exist or the loading fails, + * {@code null} is returned. + * + * @param resouceId Indicates the image resource ID. + * @param slice Indicates the Context. + * @return Returns the image. + */ + public static Optional createPixelMapByResId(int resouceId, Context slice) { + ResourceManager manager = slice.getResourceManager(); + if (manager == null) { + return Optional.empty(); + } + try { + try (Resource resource = manager.getResource(resouceId)) { + if (resource == null) { + return Optional.empty(); + } + ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions(); + srcOpts.formatHint = "image/png"; + ImageSource imageSource = ImageSource.create(readResource(resource), srcOpts); + if (imageSource == null) { + return Optional.empty(); + } + ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions(); + decodingOptions.desiredSize = new Size(0, 0); + decodingOptions.desiredRegion = new Rect(0, 0, 0, 0); + decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888; + + return Optional.of(imageSource.createPixelmap(decodingOptions)); + } + } catch (IOException | NotExistException e) { + return Optional.empty(); + } + } +} diff --git a/UI/CustomComponent/entry/src/main/resources/base/element/pattern.json b/UI/CustomComponent/entry/src/main/resources/base/element/pattern.json new file mode 100644 index 0000000000000000000000000000000000000000..4b100a434715139ad16442847747dd06629a3112 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/resources/base/element/pattern.json @@ -0,0 +1,25 @@ +{ + "pattern": [ + { + "name": "button_base", + "value": [ + { + "name": "left_padding", + "value": "24vp" + }, + { + "name": "padding", + "value": "10vp" + }, + { + "name": "top_margin", + "value": "10vp" + }, + { + "name": "text_size", + "value": "18fp" + } + ] + } + ] +} \ No newline at end of file diff --git a/UI/CustomComponent/entry/src/main/resources/base/element/string.json b/UI/CustomComponent/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..b71dcaff962a0ad4709cd1fa7d794a67ea5581a9 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/resources/base/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "app_name", + "value": "CustomComponent" + }, + { + "name": "mainability_description", + "value": "Java_Phone_Empty Feature Ability" + }, + { + "name": "annulus_button", + "value": "ColorChangingRing" + }, + { + "name": "controllers_button", + "value": "RingProgressBar" + } + ] +} \ No newline at end of file diff --git a/UI/CustomComponent/entry/src/main/resources/base/graphic/background_ability_main.xml b/UI/CustomComponent/entry/src/main/resources/base/graphic/background_ability_main.xml new file mode 100644 index 0000000000000000000000000000000000000000..6f51cad7be977df03782b897aaf8393a556a9b99 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/resources/base/graphic/background_ability_main.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/UI/CustomComponent/entry/src/main/resources/base/layout/annulus_main_ability.xml b/UI/CustomComponent/entry/src/main/resources/base/layout/annulus_main_ability.xml new file mode 100644 index 0000000000000000000000000000000000000000..3bba547c42e3f0235a503ef68f702200d7ae549e --- /dev/null +++ b/UI/CustomComponent/entry/src/main/resources/base/layout/annulus_main_ability.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/UI/CustomComponent/entry/src/main/resources/base/layout/controller_main_ability.xml b/UI/CustomComponent/entry/src/main/resources/base/layout/controller_main_ability.xml new file mode 100644 index 0000000000000000000000000000000000000000..79fabec4c6d66b53561a5f42fd105d10f104cc39 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/resources/base/layout/controller_main_ability.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/UI/CustomComponent/entry/src/main/resources/base/layout/main_ability_slice.xml b/UI/CustomComponent/entry/src/main/resources/base/layout/main_ability_slice.xml new file mode 100644 index 0000000000000000000000000000000000000000..ee29521db41c71565a9660d72472f2e2ed2e0e77 --- /dev/null +++ b/UI/CustomComponent/entry/src/main/resources/base/layout/main_ability_slice.xml @@ -0,0 +1,45 @@ + + + + +