本文选择的是Java开发模式,不是Js+Java的开发模式
一、组件、布局、事件
组件:屏幕展示出来的元素,文本、按钮、图片等。
布局:组件摆放方式
事件:可以被组件识别的操作
二、事件
常见的有:单击、双击、长按、滑动等
1.单击事件
第一种写法
自己定义实现类
修改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">
<Button
ohos:id="$+id:but1"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="click me"
ohos:text_size="100"
ohos:background_element="red"
/>
</DirectionalLayout>
为对应的页面写上如下代码
package com.example.myapplication.slice;
import com.example.myapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Button but1 = (Button)findComponentById(ResourceTable.Id_but1);
but1.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 but = (Button)component;
but.setText("Clicked");
}
}
第二种写法
当前类作为实现类,即上一篇文章中的用法
不过这里将增添一个文本,让其随点击事件而变化
由此可以知,第二种写法可以较方便的控制页面中其他组件。当然,第一种可以改写构造函数来实现。
<?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">
<Text
ohos:id="$+id:text1"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="Wait"
ohos:text_size="100"
/>
<Button
ohos:id="$+id:but1"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="click me"
ohos:text_size="100"
ohos:background_element="red"
/>
</DirectionalLayout>
package com.example.myapplication.slice;
import com.example.myapplication.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.Text;
public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
Text text1 = null;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Button but1 = (Button)findComponentById(ResourceTable.Id_but1);
text1 = (Text) findComponentById(ResourceTable.Id_text1);
but1.setClickedListener(this);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
public void onClick(Component component){
Button but = (Button)component;
text1.setText("Clicked");
but.setText("Clicked");
}
}
第三种写法
匿名内部类
只能使用一次,且外部无法得知。
package com.example.myapplication.slice;
import com.example.myapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
public class MainAbilitySlice extends AbilitySlice{
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Button but1 = (Button)findComponentById(ResourceTable.Id_but1);
but1.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
Button but = (Button)component;
but.setText("Clicked");
}
});
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
第四种写法
方法引用
需要同接口方法一致,用引用的方法作为接口的实现
onClick
package com.example.myapplication.slice;
import com.example.myapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
public class MainAbilitySlice extends AbilitySlice{
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Button but1 = (Button)findComponentById(ResourceTable.Id_but1);
but1.setClickedListener(this::onClick);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
public void onClick(Component componet){
Button btu = (Button)componet;
btu.setText("Clicked");
}
}
2.双击事件
同理
<?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">
<Text
ohos:id="$+id:text1"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="请双击"
ohos:text_size="100"
/>
<Button
ohos:id="$+id:but1"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="按钮"
ohos:text_size="100"
ohos:background_element="red"
/>
</DirectionalLayout>
package com.example.myapplication.slice;
import com.example.myapplication.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.Text;
public class MainAbilitySlice extends AbilitySlice implements Component.DoubleClickedListener {
Text text1 = null;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Button but1 = (Button)findComponentById(ResourceTable.Id_but1);
text1 = (Text)findComponentById(ResourceTable.Id_text1);
but1.setDoubleClickedListener(this);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
public void onDoubleClick(Component component) {
text1.setText("已双击");
}
}
3.长按事件
package com.example.myapplication.slice;
import com.example.myapplication.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.Text;
public class MainAbilitySlice extends AbilitySlice implements Component.LongClickedListener {
Text text1 = null;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Button but1 = (Button)findComponentById(ResourceTable.Id_but1);
text1 = (Text)findComponentById(ResourceTable.Id_text1);
but1.setLongClickedListener(this);
//but1.setLongClickable(false);在绑定事件后,通过该函数可为其能否长按属性进行改变
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
public void onLongClicked(Component component) {
text1.setText("已长按");
}
}
4.滑动事件
需要知道按下、移动、松开,即:按下位置、抬起位置
滑动事件获取
我们现在为屏幕滑动事件进行获取
需要先为布局函数准备一个ID
package com.example.myapplication.slice;
import com.example.myapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.multimodalinput.event.TouchEvent;
public class MainAbilitySlice extends AbilitySlice implements Component.TouchEventListener {
Text text1 = null;
int count = 0;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
//1.先找到整个的布局对象
DirectionalLayout dl = (DirectionalLayout) findComponentById(ResourceTable.Id_d1);
text1 = (Text) findComponentById(ResourceTable.Id_text1);
//2.为整个布局添加滑动事件
//在布局上滑动时,就会执行
//在按下、移动、松开这个过程中,程序会不断执行 onTouchEvent方法
dl.setTouchEventListener(this);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
//参数一是滑动的组件(对象也是一个组件)
//参数二是动作对象(按下,滑动,抬起)
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
int action = touchEvent.getAction();
count++;
switch(action){
case TouchEvent.PRIMARY_POINT_DOWN:{
text1.setText("已按下,\n调用次数:"+count);
break;
}
case TouchEvent.POINT_MOVE:{
text1.setText("在移动,\n调用次数:"+count);
break;
}
case TouchEvent.PRIMARY_POINT_UP: {
text1.setText("未按下,\n调用次数:"+count);
break;
}
default: {
throw new IllegalStateException("Unexpected value: " + action);
}
}
return true;
}
}
手机的坐标系
以坐上角为原点,竖直向下为Y轴正轴,水平向右为X轴正轴,垂直于屏幕向外为Z轴正轴
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
int action = touchEvent.getAction();
switch(action){
case TouchEvent.PRIMARY_POINT_DOWN:{
//鸿蒙支持多手指操作,0代表第一个手指
MmiPoint point = touchEvent.getPointerPosition(0);
float x = point.getX();
float y = point.getY();
text1.setText("("+x+","+y+")");
break;
}
case TouchEvent.POINT_MOVE:{
MmiPoint point = touchEvent.getPointerPosition(0);
float x = point.getX();
float y = point.getY();
text1.setText("("+x+","+y+")");
break;
}
case TouchEvent.PRIMARY_POINT_UP: {
MmiPoint point = touchEvent.getPointerPosition(0);
float x = point.getX();
float y = point.getY();
text1.setText("("+x+","+y+")");
break;
}
default: {
throw new IllegalStateException("Unexpected value: " + action);
}
}
return true;
}
通过获取点击点和移动点,比较其坐标变化,获取滑动方向
右滑(手指向右移动):Y轴不变,X轴变大
左滑:Y轴不变,X轴变小
上滑:X轴不变,Y轴变小
下滑:X轴不变,Y轴变大
package com.example.myapplication.slice;
import com.example.myapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;
public class MainAbilitySlice extends AbilitySlice implements Component.TouchEventListener {
Text text1 = null;
float startx = 0;
float starty = 0;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
//1.先找到整个的布局对象
DirectionalLayout dl = (DirectionalLayout) findComponentById(ResourceTable.Id_d1);
text1 = (Text) findComponentById(ResourceTable.Id_text1);
//2.为整个布局添加滑动事件
//在布局上滑动时,就会执行
//在按下、移动、松开这个过程中,程序会不断执行 onTouchEvent方法
dl.setTouchEventListener(this);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
//参数一是滑动的组件(对象也是一个组件)
//参数二是动作对象(按下,滑动,抬起)
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
int action = touchEvent.getAction();
switch(action){
case TouchEvent.PRIMARY_POINT_DOWN:{
//鸿蒙支持多手指操作,0代表第一个手指
MmiPoint point = touchEvent.getPointerPosition(0);
startx = point.getX();
starty = point.getY();
text1.setText("已点击");
break;
}
case TouchEvent.POINT_MOVE:{
break;
}
case TouchEvent.PRIMARY_POINT_UP: {
MmiPoint point = touchEvent.getPointerPosition(0);
float endx = point.getX();
float endy = point.getY();
if(endx>startx) {
if(starty>endy){
text1.setText("右上滑动");
}
else if(starty<endy){
text1.setText("右下滑动");
}
else {
text1.setText("右滑");
}
}
else if(endx <startx){
if(starty>endy){
text1.setText("左上滑动");
}
else if(starty<endy){
text1.setText("左下滑动");
}
else {
text1.setText("左滑");
}
}
else{
if(starty>endy){
text1.setText("上滑");
}
else if(starty<endy){
text1.setText("下滑");
}
else {
text1.setText("未滑动");
}
}
break;
}
default: {
throw new IllegalStateException("Unexpected value: " + action);
}
}
return true;
}
}
返回值问题
为true时:表示所有的动作都会触发当前方法并执行对应代码
为false时:只有第一个动作会触发当前方法并执行对应代码,后续不再触发