赞
踩
当Java UI框架提供的组件无法满足设计需求时,可以创建自定义组件,根据设计需求添加绘制任务,并定义组件的属性及事件响应,完成组件的自定义。
接口名 | 作用 |
---|---|
setEstimateSizeListener | 设置测量组件的侦听器。 |
onEstimateSize | 测量组件的大小以确定宽度和高度。 |
setEstimatedSize | 将测量的宽度和高度设置给组件。 |
EstimateSpec.getChildSizeWithMode | 基于指定的大小和模式为子组件创建度量规范。 |
EstimateSpec.getSize | 从提供的度量规范中提取大小。 |
EstimateSpec.getMode | 获取该组件的显示模式。 |
addDrawTask | 添加绘制任务。 |
onDraw | 通过绘制任务更新组件时调用。 |
下面以自定义圆环组件为例,介绍自定义组件的通用配置方法:在屏幕中绘制蓝色圆环,并实现点击变化圆环颜色的功能。
图1 在界面中显示的自定义圆环组件
示例代码如下:
- public class CustomComponent extends Component{
- public CustomComponent(Context context) {
- super(context);
- }
- }
- public class CustomComponent extends Component implements Component.EstimateSizeListener {
- public CustomComponent(Context context) {
- super(context);
-
- ...
-
- // 设置测量组件的侦听器
- setEstimateSizeListener(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, width, Component.EstimateSpec.NOT_EXCEED),
- Component.EstimateSpec.getChildSizeWithMode(height, height, Component.EstimateSpec.NOT_EXCEED));
- return true;
- }
- }
模式 | 作用 |
---|---|
UNCONSTRAINT | 父组件对子组件没有约束,表示子组件可以任意大小。 |
PRECISE | 父组件已确定子组件的大小。 |
NOT_EXCEED | 已为子组件确定了最大大小,子组件不能超过指定大小。 |
示例代码如下:
- public class CustomComponent extends Component implements Component.DrawTask,Component.EstimateSizeListener {
- // 圆环宽度
- private static final float CIRCLE_STROKE_WIDTH = 100f;
-
- // 绘制圆环的画笔
- private Paint circlePaint;
-
- public CustomComponent(Context context) {
- super(context);
-
- // 初始化画笔
- initPaint();
-
- // 添加绘制任务
- addDrawTask(this);
- }
-
- private void initPaint(){
- circlePaint = new Paint();
- circlePaint.setColor(Color.BLUE);
- circlePaint.setStrokeWidth(CIRCLE_STROKE_WIDTH);
- circlePaint.setStyle(Paint.Style.STROKE_STYLE);
- }
-
- @Override
- public void onDraw(Component component, Canvas canvas) {
-
- // 在界面中绘制一个圆心坐标为(500,500),半径为400的圆
- canvas.drawCircle(500,500,400,circlePaint);
- }
-
- ...
- }
- public class CustomComponent extends Component implements Component.DrawTask, Component.EstimateSizeListener, Component.TouchEventListener {
- ...
- public CustomComponent(Context context) {
- ...
-
- // 设置TouchEvent响应事件
- setTouchEventListener(this);
- }
-
- ...
-
- @Override
- public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
- switch (touchEvent.getAction()) {
- case TouchEvent.PRIMARY_POINT_DOWN:
- circlePaint.setColor(Color.GREEN);
- invalidate();
- break;
- case TouchEvent.PRIMARY_POINT_UP:
- circlePaint.setColor(Color.YELLOW);
- invalidate();
- break;
- }
- //允许触摸事件触发后进行回调,一定要为true,不然只会监听按下的点击事件,不会触发弹起的事件
- return true;
- }
- }
- @Override
- protected void onStart(Intent intent) {
- super.onStart(intent);
- DirectionalLayout.LayoutConfig config = new DirectionalLayout.LayoutConfig(
- DirectionalLayout.LayoutConfig.MATCH_PARENT, DirectionalLayout.LayoutConfig.MATCH_PARENT);
- myLayout.setLayoutConfig(config);
-
- CustomComponent customComponent = new CustomComponent(this);
- DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(1080, 1000);
- customComponent.setLayoutConfig(layoutConfig);
-
- myLayout.addComponent(customComponent);
- super.setUIContent(myLayout);
- }
接下来是绘制矩形,三角形,线条,三角形,点,绘制文字等等效果,代码如下
- @Override
- public void onDraw(Component component, Canvas canvas) {
- //绘制图形
-
- // 在界面中绘制一个圆心坐标为(500,500),半径为400的圆
- canvas.drawCircle(200,400,100,paint);
- //左上角坐标点为(100,100),右下角坐标点为(200,200),绘制一个正方形
- canvas.drawRect(100,100,200,200,paint);
- //绘制文字
- canvas.drawChars(paint,new char[]{'你','好','鸿','蒙'},100,700);
- canvas.drawCharSequence(paint,"加油华为",100,900);
- //画线
- canvas.drawLine(500,100,700,500,paint);
- //画点
- canvas.drawPoint(900,900,paint);
- //画三角形
- canvas.drawLines(new float[]{400,700,600,800,
- 600,800,500,600,
- 500,600,400,700},paint);
- }
其效果如下:绘制的图形效果和通过触摸事件点击之后的效果,手指离开屏幕后恢复颜色
整个自定义组件完整代码如下:
- package com.example.hm_phone_java.views;
-
- 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.multimodalinput.event.TouchEvent;
-
- public class CustomComponent extends Component implements Component.EstimateSizeListener, Component.DrawTask, Component.TouchEventListener {
- public CustomComponent(Context context) {
- super(context);
- //添加组件大小监听器
- setEstimateSizeListener(this);
- //初始化画笔
- initPaint();
- // 添加绘制任务
- addDrawTask(this);
-
- //添加触摸事件
- setTouchEventListener(this);
- }
-
-
- @Override
- public boolean onEstimateSize(int width, int height) {
- int w=Component.EstimateSpec.getSize(width);
- int h=Component.EstimateSpec.getSize(height);
- setEstimatedSize(
- //NOT_EXCEED 已为子组件确定了最大大小,子组件不能超过指定大小。
- //PRECISE 父组件已确定子组件的大小。
- //UNCONSTRAINT 父组件对子组件没有约束,表示子组件可以任意大小。
- Component.EstimateSpec.getChildSizeWithMode(w,w, EstimateSpec.NOT_EXCEED),
- Component.EstimateSpec.getChildSizeWithMode(h,h, EstimateSpec.NOT_EXCEED)
- );
- return true;
- }
-
- // 圆环宽度
- private static final float CIRCLE_STROKE_WIDTH = 50f;
- // 绘制圆环的画笔
- private Paint paint;
-
- public void initPaint(){
- //创建画笔
- paint=new Paint();
- //设置画笔颜色
- paint.setColor(Color.BLUE);
- //设置线条宽度
- paint.setStrokeWidth(CIRCLE_STROKE_WIDTH);
- //设置线条样式
- //STROKE_STYLE 空心线条
- //FILL_STYLE 实心
- //FILLANDSTROKE_STYLE实心和边框线条
- paint.setStyle(Paint.Style.FILL_STYLE);
- //设置绘制文字大小
- paint.setTextSize(60);
- }
-
- @Override
- public void onDraw(Component component, Canvas canvas) {
- //绘制图形
-
- // 在界面中绘制一个圆心坐标为(500,500),半径为400的圆
- canvas.drawCircle(200,400,100,paint);
- //左上角坐标点为(100,100),右下角坐标点为(200,200),绘制一个正方形
- canvas.drawRect(100,100,200,200,paint);
- //绘制文字
- canvas.drawChars(paint,new char[]{'你','好','鸿','蒙'},100,700);
- canvas.drawCharSequence(paint,"加油华为",100,900);
- //画线
- canvas.drawLine(500,100,700,500,paint);
- //画点
- canvas.drawPoint(900,900,paint);
- //画三角形
- canvas.drawLines(new float[]{400,700,600,800,
- 600,800,500,600,
- 500,600,400,700},paint);
- }
-
- @Override
- public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
- switch (touchEvent.getAction()){
- case TouchEvent.PRIMARY_POINT_DOWN:
- //自定义组件被按下,改变颜色为红色,并重新绘制,刷新图层
- paint.setColor(Color.RED);
- invalidate();
- break;
- case TouchEvent.PRIMARY_POINT_UP:
- paint.setColor(Color.BLUE);
- invalidate();
- break;
- }
- //记得将返回值改为true,表示该监听事件允许回传
- return true;
- }
- }
界面完整代码如下:
- package com.example.hm_phone_java.slice;
-
- import com.example.hm_phone_java.ResourceTable;
- import com.example.hm_phone_java.views.CustomComponent;
- import ohos.aafwk.ability.AbilitySlice;
- import ohos.aafwk.content.Intent;
- import ohos.agp.components.DirectionalLayout;
-
- public class OneCustomComponentAbilitySlice extends AbilitySlice {
-
- @Override
- protected void onStart(Intent intent) {
- super.onStart(intent);
- DirectionalLayout myLayout=new DirectionalLayout(this);
- DirectionalLayout.LayoutConfig config = new DirectionalLayout.LayoutConfig(
- DirectionalLayout.LayoutConfig.MATCH_PARENT, DirectionalLayout.LayoutConfig.MATCH_PARENT);
- myLayout.setLayoutConfig(config);
-
- CustomComponent customComponent = new CustomComponent(this);
- DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(1080, 1000);
- customComponent.setLayoutConfig(layoutConfig);
-
- myLayout.addComponent(customComponent);
- super.setUIContent(myLayout);
- }
- }
并将该界面的类名添加至MainAbility进行引用,接着开启华为模拟器即可看到自定义控件的效果。
初次学习鸿蒙的自定义控件,大家如果掌握的,可以自行绘制图形,比如五边形,六边形,五角星等等
下一篇文章将带着大家使用鸿蒙开发学习自定义组件绘制五星红旗,尽请期待
今天就分享到这里,感谢大家的关注和阅读,因最近工作比较繁忙,没有及时更新文章!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。