事件
常见的事件有:单击、双击、长按、还有触摸事件 。我们可以给文本、按钮等等组件添加不同的事件。
单击事件
四种实现方法(下面的其他事件类推):
- 自己编写实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class MainAbilitySlice extends AbilitySlice {
Button btn1; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
btn1 = (Button) findComponentById(ResourceTable.Id_btn1);
btn1.setClickedListener(new MyListener());
}
@Override public void onActive() {super.onActive();}
@Override public void onForeground(Intent intent) {super.onForeground(intent);} }
class MyListener implements Component.ClickedListener{ @Override public void onClick(Component component) { Button btn1 = (Button) component;
btn1.setText("被点了");
btn1.setClickable(false); } }
|
- 实现 Component.ClickedListener 接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
Button btn1; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
btn1 = (Button) findComponentById(ResourceTable.Id_btn1);
btn1.setClickedListener(this);
}
@Override public void onClick(Component component) { btn1.setText("被点了"); } @Override public void onActive() {super.onActive();}
@Override public void onForeground(Intent intent) {super.onForeground(intent);}
}
|
- 方法引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
Button btn1; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
btn1 = (Button) findComponentById(ResourceTable.Id_btn1);
btn1.setClickedListener(this::onClick);
}
@Override public void onClick(Component component) { btn1.setText("被点了"); }
@Override public void onActive() { super.onActive(); }
@Override public void onForeground(Intent intent) { super.onForeground(intent); } }
|
- 匿名内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class MainAbilitySlice extends AbilitySlice{
Button btn1; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
btn1 = (Button) findComponentById(ResourceTable.Id_btn1);
btn1.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { btn1.setText("被点了"); } });
}
@Override public void onActive() { super.onActive(); }
@Override public void onForeground(Intent intent) { super.onForeground(intent); } }
|
双击事件
- 接口名:DoubleClickedListener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class MainAbilitySlice extends AbilitySlice{
Button btn1; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
btn1 = (Button) findComponentById(ResourceTable.Id_btn1);
btn1.setDoubleClickedListener(new Component.DoubleClickedListener() { @Override public void onDoubleClick(Component component) { btn1.setText("被双击了"); } }); }
@Override public void onActive() { super.onActive(); }
@Override public void onForeground(Intent intent) { super.onForeground(intent); } }
|
长按事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class MainAbilitySlice extends AbilitySlice{
Button btn1; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
btn1 = (Button) findComponentById(ResourceTable.Id_btn1);
btn1.setLongClickedListener(new Component.LongClickedListener() { @Override public void onLongClicked(Component component) { btn1.setText("被长按了"); } }); }
@Override public void onActive() { super.onActive(); }
@Override public void onForeground(Intent intent) { super.onForeground(intent); } }
|
滑动事件(触摸事件)
滑动事件里面分为三个动作:按下不松,移动,抬起。
- PRIMARY_POINT_DOWN:按下不松。
- POINT_MOVE:移动。
- PRIMARY_POINT_UP:抬起。
手机坐标: 手机左上角的点为原点。 (向右为X轴 | 向下为Y轴 | 垂直于屏幕向上为Z轴)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import com.roydon.beautifyapp1.MainAbility; import com.roydon.beautifyapp1.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.Button; import ohos.agp.components.Component; import ohos.agp.components.DirectionalLayout; import ohos.agp.window.dialog.ToastDialog; import ohos.multimodalinput.event.MmiPoint; import ohos.multimodalinput.event.TouchEvent;
public class MainAbilitySlice extends AbilitySlice{
@Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
DirectionalLayout dl = (DirectionalLayout) findComponentById(ResourceTable.Id_dl);
dl.setTouchEventListener(new Component.TouchEventListener() { @Override public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
if (touchEvent.getAction()==TouchEvent.PRIMARY_POINT_DOWN){ System.out.println("按下"); System.out.println("手指按下的坐标:"+touchEvent.getPointerPosition(0)); MmiPoint position = touchEvent.getPointerPosition(0); float pointX = position.getX(); float pointY = position.getY(); }else if(touchEvent.getAction()==TouchEvent.POINT_MOVE){ System.out.println("移动"); }else if(touchEvent.getAction()==TouchEvent.PRIMARY_POINT_UP){ System.out.println("松开"); }
return true; } });
}
@Override public void onActive() { super.onActive(); }
@Override public void onForeground(Intent intent) { super.onForeground(intent); } }
|
常见组件
屏幕展示出来的元素,都称之为组件。比如华为已经提供的:文本,图片,进度条,输入框等。
组件的顶级父类:Component
组件分类
- 显示类组件 只负责数据展示的,无法跟用户交互,比如展示文本的组件,展示图片的组件。
- 交互类组件 可以跟用户交互的,比如用户可以点击的按钮组件,用户可以输入的文本框组件。
- 布局类组件 布局其实也是一种比较特殊的组件。
显示类组件
文本Text、图片Image、CommonDialog普通弹框组件、ToastDialog信息提示组件、时钟Clock、定时器 TickTimer、进度条ProgressBar等。。。
Text文本组件
常用属性:
长度单位:px,vp,fp。
如果不写单位,默认单位是px
vp(虚拟像素)长度单位。1vp=3px
fp字体大小单位。
跑马灯效果:
1 2 3 4 5 6
| text.setTruncationMode(Text.TruncationMode.AUTO_SCROLLING);
text.setAutoScrollingCount(Text.AUTO_SCROLLING_FOREVER);
text.startAutoScrolling();
|
Image图片组件
图片存放路径再media文件夹下
图片剪切显示:
- 代码中:可以用setClipGravity方法
- xml文件中:可以用clip_alignment属性
- 上、下、左、右、居中
- 表示分别按照上、下、左、右、中间部位进行剪切。
图片缩放显示:
- 代码中:可以用setScaleMode方法
- xml文件中:可以用scale_mode属性
- inside:表示将原图按比例缩放到与Image相同或更小的尺寸,并居中显示。 有可能不会填充组件
- center:表示不缩放,按Image大小显示原图中间部分。
- stretch:表示将原图缩放到与Image大小一致。 拉伸。将组件填充。
- clip_center:表示将原图按比例缩放到与Image相同或更大的尺寸,并居中显示。超过组件的部分被剪 切掉。
- zoom_center:表示原图按照比例缩放到与Image最窄边一致,并居中显示。
- zoom_end:表示原图按照比例缩放到与Image最窄边一致,并靠结束端显示。
- zoom_start:表示原图按照比例缩放到与Image最窄边一致,并靠起始端显示。
CommonDialog普通弹框组件
使用默认布局的基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
CommonDialog cd = new CommonDialog(this);
cd.setTitleText("系统定位服务已关闭");
cd.setContentText("请打开定位服务,以便司机师傅能够准确接您上车");
cd.setAutoClosable(true);
cd.setButton(0, "设置", new IDialog.ClickedListener() { @Override public void onClick(IDialog iDialog, int i) {
} }); cd.setButton(1, "取消", new IDialog.ClickedListener() { @Override public void onClick(IDialog iDialog, int i) {
cd.destroy(); } });
cd.show(); }
|
自定义弹框布局
新建弹窗布局文件,文件名: message_dialog.xml。如果需要更复杂的弹框,只要丰富xml文件中的组件即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_content" ohos:width="match_content" ohos:orientation="vertical">
<Text ohos:id="$+id:message" ohos:height="match_content" ohos:width="match_content" ohos:text_size="40fp"/>
<Button ohos:id="$+id:submit" ohos:height="match_content" ohos:width="match_content" ohos:background_element="#21a896" ohos:text="确定" ohos:text_size="40fp"/>
<Button ohos:id="$+id:cancel" ohos:height="match_content" ohos:width="match_content" ohos:background_element="#0021D9" ohos:text="取消" ohos:text_size="40fp" ohos:top_margin="10vp" /> </DirectionalLayout>
|
java类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| import com.roydon.myapplication1.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.*; import ohos.agp.window.dialog.CommonDialog;
public class MainAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
CommonDialog cd = new CommonDialog(this); cd.setCornerRadius(30); DirectionalLayout dl = (DirectionalLayout) LayoutScatter.getInstance(this).parse(ResourceTable.Layout_message_dialog, null, false);
Text title = (Text) dl.findComponentById(ResourceTable.Id_message); Button submit = (Button) dl.findComponentById(ResourceTable.Id_submit); Button cancel = (Button) dl.findComponentById(ResourceTable.Id_cancel);
title.setText("msg"); submit.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { title.setText("点击了确定按钮"); } }); cancel.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { cd.destroy(); } }); cd.setContentCustomComponent(dl); cd.show(); }
@Override public void onActive() { super.onActive(); }
@Override public void onForeground(Intent intent) { super.onForeground(intent); } }
|
封装成工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import com.roydon.myapplication1.ResourceTable; import ohos.agp.components.*; import ohos.agp.window.dialog.CommonDialog; import ohos.app.Context;
public class MyDialog { public static void showDialog(Context context, String msg) { CommonDialog cd = new CommonDialog(context); cd.setCornerRadius(30); DirectionalLayout dl = (DirectionalLayout) LayoutScatter.getInstance(context).parse(ResourceTable.Layout_message_dialog, null, false); Text title = (Text) dl.findComponentById(ResourceTable.Id_message); Button submit = (Button) dl.findComponentById(ResourceTable.Id_submit); Button cancel = (Button) dl.findComponentById(ResourceTable.Id_cancel); title.setText(msg); submit.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { title.setText("点击了确定按钮"); } }); cancel.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { cd.destroy(); } }); cd.setContentCustomComponent(dl); cd.show(); } }
|
ToastDialog信息提示组件
也叫做吐司弹框。就是一个小提示而已。 ToastDialog是CommonDialog的子类,所以具备CommonDialog相关的特性。 也包含了标题,内容还有选择按钮。 一般来讲,吐司弹框我们只用中间的内容部分,因为他出现的意义就是为了提示信息的。
基本使用:
1 2 3 4
| ToastDialog t = new ToastDialog(this); t.setText("要显示的内容") t.setAlignment(LayoutAlignment.CENTER); t.show();
|
相关设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ToastDialog toastDialog = new ToastDialog(this);
toastDialog.setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT);
toastDialog.setDuration(2000);
toastDialog.setAutoClosable(true);
toastDialog.setAlignment(LayoutAlignment.CENTER);
toastDialog.setText("要显示的内容");
toastDialog.show();
|
自定义布局和抽取工具类:
布局xml文件命名为mytoast.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_content" ohos:width="match_content" ohos:orientation="vertical">
<Text ohos:id="$+id:msg" ohos:height="match_content" ohos:width="match_content" ohos:text_size="16fp" ohos:text_color="#FFFFFF" ohos:text_alignment="center" ohos:padding="20vp" ohos:margin="30vp" ohos:multiple_lines="true" ohos:background_element="#FF5B3535"/>
</DirectionalLayout>
|
工具类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import com.roydon.myapplication1.ResourceTable; import ohos.agp.components.DirectionalLayout; import ohos.agp.components.LayoutScatter; import ohos.agp.utils.LayoutAlignment; import ohos.agp.window.dialog.ToastDialog; import ohos.app.Context;
public class MyToast {
public static void showDialog(Context context, String msg) { DirectionalLayout dl = (DirectionalLayout) LayoutScatter.getInstance(context).parse(ResourceTable.Layout_mytoast, null, false); ToastDialog td = new ToastDialog(context); td.setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT); td.setDuration(2000); td.setAutoClosable(true); td.setAlignment(LayoutAlignment.BOTTOM); td.setText(msg); td.show(); } }
|
Clock时钟组件
是Text的子类,所以可以使用Text的一些属性。
常用属性:
常用方法:
指定12小时展示格式 clock.setFormatIn12HourMode(“yyyy年MM月dd日 hh:mm:ss a”);
指定24小时展示格式 clock.setFormatIn24HourMode(“yyyy年MM月dd日 HH:mm:ss”);
拓展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static String dateToTimeStamp(String s) throws ParseException{ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = simpleDateFormat.parse(s); long ts = date.getTime(); String res = String.valueOf(ts); return res; }
public static String timeStampToDate(String s){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); long lt = new Long(s); Date date = new Date(lt); String res = simpleDateFormat.format(date); return res; }
|
TickTimer定时器组件
是Text的子类,所以可以使用Text的一些属性。
1 2 3 4 5 6 7 8 9 10 11 12
| <TickTimer ohos:id="$+id:my_tt" ohos:height="60vp" ohos:width="250vp" ohos:padding="10vp" ohos:text_size="20fp" ohos:text_color="#ffffff" ohos:background_element="#0000ff" ohos:text_alignment="center" ohos:layout_alignment="horizontal_center" ohos:top_margin="50vp" /> //没有设置时间,默认是从1970年1月1日开始。
|
ProgressBar进度条组件
.getProgress();//获取进度条里面原本的值
.setProgressValue(progress);//设置进度值
.setProgressHintText(progress + “%”);//修改提示文字进度
1 2 3 4 5 6 7 8 9 10 11
| <ProgressBar ohos:id="$+id:pb" ohos:height="match_content" ohos:width="300vp" ohos:progress="0" ohos:progress_hint_text="0%" ohos:progress_hint_text_color="#000000" ohos:progress_width="50vp" ohos:progress_color="#FF0000" ohos:max="100" ohos:min="0"/>
|
RoundProgressBar
是ProgressBar的子类,用法跟ProgressBar一模一样,只是显示的方式不一样。
1 2 3 4 5 6 7 8 9 10 11
| <RoundProgressBar ohos:height="300vp" ohos:width="300vp" ohos:progress_hint_text="80%" ohos:progress_hint_text_size="50vp" ohos:progress_hint_text_color="#000000" ohos:progress="80" ohos:progress_width="20vp" ohos:progress_color="#FF0000" ohos:max="100" ohos:min="0"/>
|
交互类组件
TextField文本输入框组件
是Text的子类,用来进行用户输入数据的。
将文本框中的密码变成明文:textField.setTextInputType(InputAttribute.PATTERN_NULL);
将文本框中的密码变回密文:textField.setTextInputType(InputAttribute.PATTERN_PASSWORD);
取消按钮设置位置:int x = r.nextInt(500); int y = r.nextInt(1000);cacel.setTranslation(x,y);
1 2 3 4 5 6 7 8 9 10 11
| <TextField ohos:id="$+id:text" ohos:height="50vp" ohos:width="319vp" ohos:background_element="#FFFFFF" ohos:hint="请输入信息" ohos:hint_color="#999999" ohos:layout_alignment="horizontal_center" ohos:text_alignment="center" ohos:text_size="17fp" ohos:top_margin="100vp"/>
|
Checkbox多选框组件
父类是AbsButton,而AbsButton的父类是Button。 当我们需要同时选择多个元素的时候就需要用到多选框组件。
比如:发送图片的时候需要多选,注册的时候选择爱好也需要多选等。
可以给多选框添加一个状态监听事件 checkbox.setCheckedStateChangedListener(this);
1
| public class MainAbilitySlice extends AbilitySlice implements AbsButton.CheckedStateChangedListener
|
1 2 3 4 5 6 7 8 9 10 11
|
@Override public void onCheckedChanged(AbsButton absButton, boolean b) { if(b){ ToastUtils.showDialog(this,"被选中"); }else{ ToastUtils.showDialog(this,"未被选中"); } }
|
父类是AbsButton,而AbsButton的父类是Button。在使用的时候需要用到单选按钮的按钮组。 RadioContainer,在一组内多选按钮只能选择其中一个。
当需要监听单选框的状态时,不要用AbsButton里面的CheckedStateChangedListener。而是给按钮组 RadioContainer添加事件。用RadioContainer里面的CheckedStateChangedListener。
按钮组RadioContainer常见方法:.setMarkChangedListener () //添加状态监听事件,可以监听按钮组里面单选按钮的状态是否改变
1
| public class MainAbilitySlice extends AbilitySlice implements RadioContainer.CheckedStateChangedListener
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <RadioContainer ohos:id="$+id:rc" ohos:height="match_content" ohos:width="match_content">
<RadioButton ohos:id="$+id:boy" ohos:height="match_content" ohos:width="match_content" ohos:background_element="#21a8fd" ohos:marked="false" ohos:text="男" ohos:text_alignment="center" ohos:text_size="30fp" /> <RadioButton ohos:id="$+id:girl" ohos:height="match_content" ohos:width="match_content" ohos:background_element="#21a8fd" ohos:marked="false" ohos:text="女" ohos:text_alignment="center" ohos:text_size="30fp" ohos:top_margin="10vp"/> </RadioContainer>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| RadioContainer rc = (RadioContainer) findComponentById(ResourceTable.Id_rc); rc.setMarkChangedListener(this);
@Override public void onCheckedChanged(RadioContainer radioContainer, int i) { RadioButton rb = (RadioButton) radioContainer.getComponentAt(i); String text = rb.getText(); if(rb.isChecked()){ ToastUtils.showDialog(this,text + "被选中了"); }else{ ToastUtils.showDialog(this,text + "被取消选中了"); } }
|
Switch组件
滑道背景 ohos:track_element=”#FF0000”
滑块颜色 ohos:thumb_element=”#07C160”
1 2 3 4 5 6 7 8
| <Switch ohos:id="$+id:choose" ohos:height="40vp" ohos:width="100vp" ohos:text_state_on="开" ohos:text_state_off="关" ohos:text_size="20vp" />
|
监听状态改变:
1
| public class MainAbilitySlice extends AbilitySlice implements AbsButton.CheckedStateChangedListener
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Switch choose = (Switch) findComponentById(ResourceTable.Id_choose); choose.setCheckedStateChangedListener(this);
@Override public void onCheckedChanged(AbsButton absButton, boolean b) { if(b){ }else{ } }
|
Slider滑块组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <Slider ohos:height="50vp" ohos:width="300vp" 进度颜色,左边的 ohos:progress_color="#FF0000" 滑块颜色 ohos:thumb_element="#00FF00" 未完成进度颜色 ohos:background_instruct_element="#0000FF" 次一级的进度值 ohos:vice_progress="80" 次一级的进度颜色 ohos:vice_progress_element="#923456" 是否允许用户操作滑块 ohos:enabled="true" max = "100" min = "0" />
|
事件:ValueChangedListener(值改变事件)
接口中的方法:
①:onProgressUpdated(参数一,参数二,参数三) 当滑块组件中的值改变的时候,调用该方法。
参数一:滑块对象
参数二:当前进度值
参数三:当前滑块组件是否可以调节进度
②:onTouchStart 按上滑块的时候触发
③:onTouchend 离开滑块的时候触发
1
| public class MainAbilitySlice extends AbilitySlice implements Slider.ValueChangedListener
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| Slider slider = (Slider) findComponentById(ResourceTable.Id_slider); slider.setValueChangedListener(this);
@Override public void onProgressUpdated(Slider slider, int i, boolean b) { ToastUtils.showDialog(this,"当前的进度值为:" + i); }
@Override public void onTouchStart(Slider slider) { ToastUtils.showDialog(this,"按下不松"); }
@Override public void onTouchEnd(Slider slider) { ToastUtils.showDialog(this,"松开"); }
|
ListContainer
ListContainer是一个列表容器类组件。在这里的每一行,我们都可以看做是一个item。如下图所示,包裹了所有 item的红色的容器,就是ListContainer
注意细节:
① 每一行其实就是一个独立的item。
② 在屏幕的上面和下面,还有很多没有展示出来的item。 当我们用手指往上滑动的时候,就可以到下面的item。 当我们用手指往下滑动的时候,就可以到上面的item。 只不过划出屏幕的item会被销毁,而没有划入屏幕的item 还没有创建出来。
③ 如果item过多,在内存会有垃圾。这个问题下面学习。
1 2 3 4 5
| <ListContainer ohos:id="$+id:listcontainer" ohos:height="match_parent" ohos:width="match_parent" ohos:layout_alignment="horizontal_center"/>
|
实现步骤:
- 给item去指定一个布局xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_content" ohos:width="match_content" ohos:orientation="horizontal"> <Text ohos:id="$+id:text" ohos:height="match_content" ohos:width="match_content" ohos:text="00:00" ohos:text_size="20fp"/> </DirectionalLayout>
|
- 书写一个javabean类表示item
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Item {
private String text; public Item() {} public Item(String text) { this.text = text; } public String getText() { return text; } public void setText(String text) { this.text = text; } }
|
- 写一个适配器类去管理item
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| import com.roydon.listcontainerdemo1.ResourceTable; import com.roydon.listcontainerdemo1.bean.Item; import ohos.aafwk.ability.AbilitySlice; import ohos.agp.components.*;
import java.util.ArrayList;
public class ItemProvider extends BaseItemProvider { private ArrayList<Item> list; private AbilitySlice as;
public ItemProvider(ArrayList<Item> list, AbilitySlice as) { this.list = list; this.as = as; }
public ArrayList<Item> getList() { return list; }
public void setList(ArrayList<Item> list) { this.list = list; }
public AbilitySlice getAs() { return as; }
public void setAs(AbilitySlice as) { this.as = as; }
@Override public int getCount() { return list.size(); }
@Override public Object getItem(int i) { if (list != null && i >= 0 && i < list.size()) { return list.get(i); } return null; }
@Override public long getItemId(int i) { return i; }
@Override public Component getComponent(int i, Component component, ComponentContainer componentContainer) { DirectionalLayout dl; if (component != null) { dl = (DirectionalLayout) component; } else { dl = (DirectionalLayout) LayoutScatter.getInstance(as).parse(ResourceTable.Layout_list_item, null, false); } Text text = (Text) dl.findComponentById(ResourceTable.Id_text); text.setText(list.get(i).getText()); return dl; } }
|
- 将适配器交给ListContainer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import com.roydon.listcontainerdemo1.ResourceTable; import com.roydon.listcontainerdemo1.bean.Item; import com.roydon.listcontainerdemo1.provider.ItemProvider; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.ListContainer;
import java.util.ArrayList;
public class MainAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main);
ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_listContainer);
ItemProvider itemProvider = new ItemProvider(getData(), this); listContainer.setItemProvider(itemProvider);
}
@Override public void onActive() { super.onActive(); }
@Override public void onForeground(Intent intent) { super.onForeground(intent); }
public ArrayList<Item> getData() { ArrayList<Item> list = new ArrayList<>(); for (int i = 0; i < 50; i++) { list.add(new Item("item-->" + i)); } return list; }
}
|
案例:微信消息
Picker
picker是滑动选择器组件。在一些app中选择地址的时候会用到,但是一般是三个picker选择器组合在一起使用。 如图所示:
案例:选择今天星期几
1 2 3 4 5 6 7 8 9 10 11 12 13
| <Picker ohos:id="$+id:picker" ohos:height="match_content" ohos:width="100vp" ohos:max_value="6" ohos:min_value="0" ohos:normal_text_color="#21a8fd" ohos:normal_text_size="20fp" ohos:selected_text_color="#FF0000" ohos:selected_text_size="20fp" ohos:shader_color="pink" ohos:value="0" />
|
1 2 3 4 5 6 7 8 9 10 11 12
| Picker picker = (Picker) findComponentById(ResourceTable.Id_picker);
ArrayList<String> list = new ArrayList<>(); list.add("星期一"); list.add("星期二"); list.add("星期三"); list.add("星期四"); list.add("星期五"); list.add("星期六"); list.add("星期日");
picker.setFormatter(list::get)
|
Picker联动时
1
| public class MainAbilitySlice extends AbilitySlice implements Picker.ValueChangedListener
|
1 2 3 4 5 6 7 8 9 10 11 12 13
|
@Override public void onValueChanged(Picker picker, int oldValue, int newValue) { if (picker == province) { Province chooseProvince = provinceList.get(newValue); city.setMaxValue(chooseProvince.getList().size() - 1); city.setFormatter(i -> chooseProvince.getList().get(i)); city.setValue(0); } }
|
案例:省市区三级联动
DatePicker和TimePicker
DatePicker和TimePicker都是时间选择器。
DatePicker:表示年月日
TimePicker:表示时分秒
1 2 3 4 5 6 7 8 9 10 11 12
| <DatePicker ohos:id="$+id:datepicker" ohos:height="match_content" ohos:width="300vp" ohos:normal_text_size="20fp" ohos:selected_text_size="20fp"/> <TimePicker ohos:id="$+id:timepicker" ohos:height="match_content" ohos:width="300vp" ohos:normal_text_size="20fp" ohos:selected_text_size="20fp"/>
|
DatePicker监听:
1
| public class MainAbilitySlice extends AbilitySlice implements DatePicker.ValueChangedListener
|
1 2 3 4 5 6
| DatePicker datePicker = (DatePicker) findComponentById(ResourceTable.Id_datepicker); datePicker.setValueChangedListener(this); @Override public void onValueChanged(DatePicker datePicker, int year, int month, int day) { text.setText(year + "年" + month + "月" + day + "日"); }
|
TimePicker监听:
1 2 3 4 5 6 7
| TimePicker timePicker = (TimePicker) findComponentById(ResourceTable.Id_timepicker); timePicker.setTimeChangedListener(new TimePicker.TimeChangedListener() { @Override public void onTimeChanged(TimePicker timePicker, int hour, int minutes, int second) { text.setText("时间为:" + hour + minutes + second); } });
|
美化组件
美化外形
- 组件外形(方形,圆角,胶囊形,圆形)
- 组件边框(颜色,粗细) 背景颜色(有色号就行)
- 背景渐变(线形或者辐射形)
美化状态
组件在不同状态时显示不同的样式。
暂时掌握三中状态:
- 默认状态 (所有组件都有默认状态)
- 按下状态 (组件按下不松时的状态)
- 选中状态 (开关组件,多选按钮,单选按钮的开启状态)
shape标签
在graphic包中新建xml,根标签为:shape就可以自定义组件的形状。
根标签:shape
1 2 3 4 5 6 7 8
| <?xml version="1.0" encoding="UTF-8" ?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <solid ohos:color="#FFFFFF"/> <corners ohos:radius="15vp"/> </shape>
|
根标签包含一个属性:shape —> ohos:shape=”rectangle”
常用值: 1. rectangle:长方形 2. oval:椭圆
根标签包含五个子标签:
① stroke:绘制边框
② corners:圆角
③ solid:背景填充
- 属性:
- color 只能指定一个颜色
- colors 可以指定多个颜色,渐变。
④ bounds:边框 可以单独设置上下左右的边框。
⑤ gradient:渐变
- 属性:
- shader_type:类型 —- radial(辐射) linear(线性)
state-container标签
在graphic包中新建xml,根标签为:state-container ,就可以在不同状态下美化组件
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="utf-8"?> <state-container xmlns:ohos="http://schemas.huawei.com/res/ohos">
/按下 <item ohos:state="component_state_pressed" ohos:element="#000000"/> //打开状态 <item ohos:state="component_state_checked" ohos:element="#FF0000"/> //默认状态:要写在最下面 <item ohos:state="component_state_empty" ohos:element="#21a8f6"/>
</state-container>
|
- 默认状态: component_state_empty (必须要写在最下面)
- 按下不松的状态: component_state_pressed
- 打开状态: component_state_checked
element中可以写指定的色号,也可以指定根标签为shape的xml文件,也可以指定固定的图片。