<Image
ohos:id="$+id:img"
ohos:height="match_content"
ohos:width="match_content"
ohos:center_in_parent="true"
ohos:image_src="$media:HarmonyOS"
/>
Image image = (Image)findComponentById(ResourceTable.Id_img); //image.setScaleMode(Image.ScaleMode.CENTER); image.setScaleMode(Image.ScaleMode.INSIDE); image.setClickedListener(new ClickedListener() { private int minWidth = 0, maxWidth, deltaWidth, deltaHeight; @Override public void onClick(Component component) { int curWidth = image.getWidth(); int curHeight = image.getHeight(); if (minWidth == 0) { minWidth = curWidth / 5; maxWidth = curWidth; deltaWidth = -curWidth / 5; deltaHeight = -curHeight / 5; } for (;;) { int newWidth = curWidth + deltaWidth; int newHeight = curHeight + deltaHeight; if (minWidth <= newWidth && newWidth <= maxWidth) { image.setWidth(newWidth); image.setHeight(newHeight); break; } else { deltaWidth *= -1; deltaHeight *= -1; } } } });
例程:Image
...\Image\entry\src\main\resources\base\media\HarmonyOS.png
...\Image\entry\src\main\resources\base\layout\ability_main.xml
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical" ohos:background_element="#000000"> <Image ohos:id="$+id:img" ohos:height="match_content" ohos:width="match_content" ohos:image_src="$media:HarmonyOS" /> </DirectionalLayout>
...\Image\entry\src\main\java\com\minwei\image\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { ... Image image = (Image)findComponentById(ResourceTable.Id_img); //image.setScaleMode(Image.ScaleMode.CENTER); image.setScaleMode(Image.ScaleMode.INSIDE); image.setClickedListener(new ClickedListener() { private int minWidth = 0, maxWidth, deltaWidth, deltaHeight; @Override public void onClick(Component component) { int curWidth = image.getWidth(); int curHeight = image.getHeight(); if (minWidth == 0) { minWidth = curWidth / 5; maxWidth = curWidth; deltaWidth = -curWidth / 5; deltaHeight = -curHeight / 5; } for (;;) { int newWidth = curWidth + deltaWidth; int newHeight = curHeight + deltaHeight; if (minWidth <= newWidth && newWidth <= maxWidth) { image.setWidth(newWidth); image.setHeight(newHeight); break; } else { deltaWidth *= -1; deltaHeight *= -1; } } } }); } ... }
运行效果如下图所示:
selector_item_num - 显示的项目数量 normal_text_size - 未选中文本大小 normal_text_color - 未选中文本颜色 selected_text_size - 被选中文本大小 selected_text_color - 被选中文本颜色 selected_normal_text_margin_radio - 被选中文本和未选中文本的边距比例 shader_color - 着色器颜色 top_line_element - 被选中项的顶线 bottom_line_element - 被选中项的底线 wheel_mode_enabled - 是否轮转显示 max_value - 最大值 min_value - 最小值 value - 当前值 element_padding - 文本和Element之间的间距 Element必须通过setElementFormatter 接口配置
picker.setMinValue(...); picker.setMaxValue(...); picker.setDisplayedData(...);
picker.setValueChangedListener( (picker, last, next) -> { ... });
例程:Picker
...\Picker\entry\src\main\resources\base\layout\ability_main.xml
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical"> <DirectionalLayout ohos:height="0vp" ohos:weight="1" ohos:width="match_parent"> <Text ohos:id="$+id:txtNumber" ohos:height="match_content" ohos:width="match_parent" ohos:text_size="26fp" ohos:text_color="#ff0000" ohos:text_alignment="horizontal_center" /> <Picker ohos:id="$+id:pckNumber" ohos:height="match_parent" ohos:weight="1" ohos:width="match_parent" ohos:background_element="#ffe1ff" ohos:normal_text_size="20fp" ohos:selected_text_size="26fp" ohos:min_value="100" ohos:max_value="500" ohos:value="300" /> </DirectionalLayout> <DirectionalLayout ohos:height="0vp" ohos:weight="1" ohos:width="match_parent" ohos:orientation="horizontal"> <DirectionalLayout ohos:height="match_parent" ohos:width="0vp" ohos:weight="1"> <Picker ohos:id="$+id:pckWeek" ohos:height="match_parent" ohos:weight="1" ohos:width="match_parent" ohos:background_element="#00a2e8" ohos:normal_text_size="20fp" ohos:normal_text_color="#ffffff" ohos:selected_text_size="26fp" ohos:selected_text_color="#ff7f27" ohos:wheel_mode_enabled="true" /> <Text ohos:id="$+id:txtWeek" ohos:height="match_content" ohos:width="match_parent" ohos:text_size="26fp" ohos:text_color="#ff0000" ohos:text_alignment="horizontal_center" /> </DirectionalLayout> <DirectionalLayout ohos:height="match_parent" ohos:width="0vp" ohos:weight="1"> <Picker ohos:id="$+id:pckHour" ohos:height="match_parent" ohos:weight="1" ohos:width="match_parent" ohos:background_element="#22b14c" ohos:normal_text_size="20fp" ohos:normal_text_color="#ffffff" ohos:selected_text_size="26fp" ohos:selected_text_color="#ffff00" ohos:top_line_element="#ffff00" ohos:bottom_line_element="#ffff00" ohos:wheel_mode_enabled="true" /> <Text ohos:id="$+id:txtHour" ohos:height="match_content" ohos:width="match_parent" ohos:text_size="26fp" ohos:text_color="#ff0000" ohos:text_alignment="horizontal_center" /> </DirectionalLayout> <DirectionalLayout ohos:height="match_parent" ohos:width="0vp" ohos:weight="1"> <Picker ohos:id="$+id:pckMinute" ohos:height="match_parent" ohos:weight="1" ohos:width="match_parent" ohos:background_element="#ff7f27" ohos:normal_text_size="20fp" ohos:normal_text_color="#ffffff" ohos:selected_text_size="26fp" ohos:selected_text_color="#00a2e8" ohos:wheel_mode_enabled="true" /> <Text ohos:id="$+id:txtMinute" ohos:height="match_content" ohos:width="match_parent" ohos:text_size="26fp" ohos:text_color="#ff0000" ohos:text_alignment="horizontal_center" /> </DirectionalLayout> </DirectionalLayout> </DirectionalLayout>
...\Picker\entry\src\main\java\com\minwei\picker\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private Picker pckNumber, pckWeek, pckHour, pckMinute; private Text txtNumber, txtWeek, txtHour, txtMinute; final private String[] weeks = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"}; private String[] hours = new String[24], minutes = new String[60]; @Override public void onStart(Intent intent) { ... pckNumber = (Picker)findComponentById(ResourceTable.Id_pckNumber); pckWeek = (Picker)findComponentById(ResourceTable.Id_pckWeek); pckHour = (Picker)findComponentById(ResourceTable.Id_pckHour); pckMinute = (Picker)findComponentById(ResourceTable.Id_pckMinute); txtNumber = (Text)findComponentById(ResourceTable.Id_txtNumber); txtWeek = (Text)findComponentById(ResourceTable.Id_txtWeek); txtHour = (Text)findComponentById(ResourceTable.Id_txtHour); txtMinute = (Text)findComponentById(ResourceTable.Id_txtMinute); pckNumber.setValueChangedListener((picker, last, next) -> { txtNumber.setText(String.valueOf(next)); }); txtNumber.setText(String.valueOf(pckNumber.getValue())); pckWeek.setMinValue(0); pckWeek.setMaxValue(weeks.length - 1); pckWeek.setDisplayedData(weeks); pckWeek.setValueChangedListener((picker, last, next) -> { txtWeek.setText(weeks[next]); }); pckWeek.setValue(0); for (int i = 0; i < hours.length; ++i) hours[i] = String.format("%d时", i); pckHour.setMinValue(0); pckHour.setMaxValue(hours.length - 1); pckHour.setDisplayedData(hours); pckHour.setValueChangedListener((picker, last, next) -> { txtHour.setText(hours[next]); }); pckHour.setValue(0); for (int i = 0; i < minutes.length; ++i) minutes[i] = String.format("%d分", i); pckMinute.setMinValue(0); pckMinute.setMaxValue(minutes.length - 1); pckMinute.setDisplayedData(minutes); pckMinute.setValueChangedListener((picker, last, next) -> { txtMinute.setText(minutes[next]); }); pckMinute.setValue(0); } ... }
运行效果如下图所示:
date_order - 显示格式
datePicker.setMinDate(...); datePicker.setMaxDate(...);
datePicker.setValueChangedListener( (datePicker, year, month, dayOfMonth) -> { ... });
例程:DatePicker
...\DatePicker\entry\src\main\resources\base\layout\ability_main.xml
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical" ohos:background_element="#000000"> <Text ohos:id="$+id:txt" ohos:height="0vp" ohos:weight="1" ohos:width="match_parent" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="center" /> <DatePicker ohos:id="$+id:dp" ohos:height="0vp" ohos:weight="1" ohos:width="match_parent" ohos:background_element="#00a2e8" ohos:normal_text_size="20fp" ohos:normal_text_color="#ffffff" ohos:selected_text_size="26fp" ohos:selected_text_color="#ff7f27" ohos:top_line_element="#ff7f27" ohos:bottom_line_element="#ff7f27" ohos:wheel_mode_enabled="true" ohos:date_order="year-month-day" /> </DirectionalLayout>
...\DatePicker\entry\src\main\java\com\minwei\datepicker\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private Text text; private DatePicker datePicker; @Override public void onStart(Intent intent) { ... text = (Text)findComponentById(ResourceTable.Id_txt); datePicker = (DatePicker)findComponentById(ResourceTable.Id_dp); text.setText( datePicker.getYear() + "年" + datePicker.getMonth() + "月" + datePicker.getDayOfMonth() + "日"); SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); try { datePicker.setMinDate(formatter.parse("19000101").getTime() / 1000); datePicker.setMaxDate(formatter.parse("22001231").getTime() / 1000); } catch (ParseException exception) { exception.printStackTrace(); } datePicker.setValueChangedListener( (datePicker, year, month, dayOfMonth) -> { text.setText(year + "年" + month + "月" + dayOfMonth + "日"); }); } ... }
运行效果如下图所示:
任何自定义的组件类都必须是Component类的子类,并在其四个版本的构造方法中将构造参数透传给基类。对于高度定制(即直接从Component类继承)的组件,还需要通过基类的addDrawTask()方法,添加一个实现了DrawTask接口的对象,该对象的onDraw()方法负责自定义组件的绘制。
public class CustomComponent extends Component implements DrawTask { public CustomComponent(Context context) { super(context); addDrawTask(this); } public CustomComponent(Context context, AttrSet attrSet) { super(context, attrSet); addDrawTask(this); } public CustomComponent(Context context, AttrSet attrSet, String styleName) { super(context, attrSet, styleName); addDrawTask(this); } public CustomComponent(Context context, AttrSet attrSet, int resId) { super(context, attrSet, resId); addDrawTask(this); } @Override public void onDraw(Component component, Canvas canvas) { // 绘制组件 ... } }
构造方法包含如下参数:
组件的绘制需要用到画布(Canvas)和画笔(Paint),它们隶属于鸿蒙操作系统高级图形平台(Advanced Graphic Platform, AGP)核心类库。该类库位于ohos.agp.render包内。
Canvas类提供了许多与图形绘制有关的方法:
方法 | 描述 |
---|---|
drawPoint() drawPoints() |
绘制点 |
drawLine() drawLines() |
绘制线 |
drawPath() | 绘制路径 |
drawRect() | 绘制矩形 |
drawRoundRect() | 绘制圆角矩形 |
drawCircle() | 绘制圆形 |
drawOval() | 绘制椭圆 |
drawChars() drawCharSequence() drawText() drawTextOnPath() |
绘制文本 |
drawDeformedPixelMap() drawPixelMapHolder() drawPixelMapHolderRect() drawPixelMapHolderCircleShape() |
绘制PixelMapHolder |
Canvas类的许多绘图方法都需要以Paint类型的画笔对象作为参数,画笔中包含了颜色、粗细、透明度、样式、字体等信息,这些信息通过Paint类的方法进行设置:
方法 | 描述 |
---|---|
setColor() | 设置颜色 |
setAlpha() | 设置透明度 |
setCornerPathEffectRadius() | 设置圆角半径 |
setStrokeCap() | 设置线端样式 |
setStrokeJoin() | 设置线肘样式 |
setStrokeMiter() | 设置尖肘截断长度 |
setStrokeWidth() | 设置线宽 |
setDashPathEffectPhase() | 设置虚线的起始偏移量 |
setDashPathEffectIntervals() | 设置虚线的划长和间隔 |
setStyle() | 设置样式 |
setFont() | 设置字体 |
setTextSize() | 设置文本大小 |
setFakeBoldText() | 设置文本加粗 |
setTextAlign() | 设置文本对齐方式 |
setPosition() | 设置文本起始位置 |
setLetterSpacing() | 设置字符间距 |
setMultipleLine() | 是否绘制多行文本 |
setUnderLine() | 是否绘制下划线 |
setStrikeThrough() | 是否绘制删除线 |
着色器用于控制图形的着色样式:
着色器 | 类 | ShaderType |
---|---|---|
线性着色器 | LinearShader | LINEAR_SHADER |
径向着色器 | RadialShader | RADIAL_SHADER |
扫描着色器 | SweepShader | SWEEP_SHADER |
位图着色器 | PixelMapShader | PIXELMAP_SHADER |
组合着色器 | GroupShader | GROUP_SHADER |
通过Paint对象的setShader()方法为画笔设置着色器:
LinearShader shader = new LinearShader(...); paint.setShader(shader, ShaderType.LINEAR_SHADER);
掩码过滤器用于控制图形的阴影样式,其值取自Blur类型的枚举:
掩码过滤器 | Blur |
---|---|
正常阴影 | NORMAL |
实体阴影 | SOLID |
内部阴影 | INNER |
外部阴影 | OUTER |
通过Paint对象的setMaskFilter()方法为画笔设置掩码过滤器:
MaskFilter maskFilter = new MaskFilter(... Blur.OUTER ...); paint.setMaskFilter(maskFilter);
在布局描述文件中,以类似下面这样的方式,引用自定义组件:
<com.minwei.custom.components.CustomComponent
ohos:height="340px"
ohos:width="340px"
/>
例程:Custom
...\Custom\entry\src\main\java\com\minwei\custom\components\CustomComponent.java
package com.minwei.custom.components; import ohos.agp.components.AttrSet; import ohos.agp.components.Component; import ohos.agp.components.Component.DrawTask; import ohos.agp.render.Canvas; import ohos.agp.render.LinearShader; import ohos.agp.render.MaskFilter; import ohos.agp.render.MaskFilter.Blur; import ohos.agp.render.Paint; import ohos.agp.render.Paint.ShaderType; import ohos.agp.render.Shader.TileMode; import ohos.agp.utils.Color; import ohos.agp.utils.Point; import ohos.app.Context; public class CustomComponent extends Component implements DrawTask { public CustomComponent(Context context) { super(context); addDrawTask(this); } public CustomComponent(Context context, AttrSet attrSet) { super(context, attrSet); addDrawTask(this); } public CustomComponent(Context context, AttrSet attrSet, String styleName) { super(context, attrSet, styleName); addDrawTask(this); } public CustomComponent(Context context, AttrSet attrSet, int resId) { super(context, attrSet, resId); addDrawTask(this); } @Override public void onDraw(Component component, Canvas canvas) { Paint paint = new Paint(); Point[] points = new Point[] {new Point(0, 0), new Point(300, 300)}; float[] stops = new float[] {0, 1}; Color[] colors = new Color[] {Color.WHITE, Color.BLACK}; TileMode tileMode = TileMode.REPEAT_TILEMODE; LinearShader shader = new LinearShader( points, stops, colors, tileMode); paint.setShader(shader, ShaderType.LINEAR_SHADER); MaskFilter maskFilter = new MaskFilter(20, Blur.OUTER); paint.setMaskFilter(maskFilter); canvas.drawCircle(170, 170, 150, paint); } }
...\Custom\entry\src\main\resources\base\layout\ability_main.xml
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical"> <com.minwei.custom.components.CustomComponent ohos:height="340px" ohos:width="340px" /> </DirectionalLayout>
运行效果如下图所示: