1. 滑動事件擷取手指位置
- 滑動事件的三個動作:

- 擷取手指的位置就涉及到坐标的概念,通過擷取到
就可以缺任意一個點的位置x、y、z
- 手機中的坐标:
- 除了 x、y軸,還有z軸,在鴻蒙手機當中,完整的坐标如下,是一個立體的三維體系,但平時z軸用的非常少,一般情況隻需考慮x、y軸就行了。
- 結合滑動事件的三個動作和坐标來分析滑動
2. 擷取按下時手指的位置(坐标)
- 擷取的這些資料其實都被鴻蒙作業系統封裝到
這個動作對象當中,通過動作去調用TouchEvent
方法,需要傳遞一個值。鴻蒙系統支援多手指的操作,比如:可以用兩個手指對圖檔進行放大或縮小,是以在getPointerPosition
需要傳遞一個索引,一個手指操作傳遞的值為 ,表示要擷取的是第一個手指的位置,他的位置也是封裝成一個對象,再用坐标對象分别擷取到getPointerPosition
坐标。x、y
//擷取按下時手指的位置(坐标)
MmiPoint point = touchEvent.getPointerPosition(0);
//x、y表示按下時手指的位置
float x = point.getX();
float y = point.getY();
text1.setText(x + "---" + y);
3. 實作案例:把按下、移動、松開的位置分别設定到文本框當中
- 建立項目:ListenerApplication4
ability_main
- 采用預設生成的Text文本内容,在此基礎上給DirectionalLayout布局和Text元件分别加上id
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
ohos:id="$+id:dl"
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:background_element="$graphic:background_ability_main"
ohos:layout_alignment="horizontal_center"
ohos:text="$string:mainability_HelloWorld"
ohos:text_size="40vp"
/>
</DirectionalLayout>
MainAbilitySlice
- 采用目前類作為實作類接口的方式編寫
package com.xdr630.listenerapplication.slice;
import com.xdr630.listenerapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.multimodalinput.event.TouchEvent;
public class MainAbilitySlice extends AbilitySlice implements Component.TouchEventListener {
Text text1 = null;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
//1.先找到整個布局對象
DirectionalLayout dl = (DirectionalLayout) findComponentById(ResourceTable.Id_dl);
text1 = (Text) findComponentById(ResourceTable.Id_text1);
//2.給整個布局添加滑動事件
//當我們在整個布局滑動的時候,就會調用本類中的onTouchEvent方法
//在按下 移動、松開的過程,代碼會不斷去調用本類中的 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) {
//參數1:component表示滑動的元件(布局也是一種元件,是以也可以用component表示布局對象)
//實際上此時代表的就是DirectionalLayout布局對象,這個布局是鋪滿整個螢幕的
//參數2:touchEvent表示動作對象(按下、滑動、擡起)
//擷取目前手指對螢幕進行操作(按下、滑動、擡起)
int action = touchEvent.getAction();
// 1:表示按下操作
// 2:表示松開操作
// 3. 表示滑動/移動操作
if (action == TouchEvent.PRIMARY_POINT_DOWN){
//隻要寫按下時需要運作的代碼即可
//擷取按下時手指的位置(坐标)
MmiPoint point = touchEvent.getPointerPosition(0);
//x、y表示按下時手指的位置
float x = point.getX();
float y = point.getY();
text1.setText(x + "---" + y);
}else if (action == TouchEvent.POINT_MOVE){
//移動或滑動
//擷取按下時手指的位置(坐标)
MmiPoint point = touchEvent.getPointerPosition(0);
//x、y表示按下時手指的位置
float x = point.getX();
float y = point.getY();
text1.setText(x + "---" + y);
}else if (action == TouchEvent.PRIMARY_POINT_UP){
//松開或擡起
//擷取按下時手指的位置(坐标)
MmiPoint point = touchEvent.getPointerPosition(0);
//x、y表示按下時手指的位置
float x = point.getX();
float y = point.getY();
text1.setText(x + "---" + y);
}
return true;
}
}
- 運作:
- 按下并且移動滑鼠時,坐标數值就會随着滑鼠的移動而變化
4. 根據手指的位置來确定是上、下、左、右哪個滑動
- 首先把按下時的 x、y 移動
方法外面去,因為如果沒有移動外面去,當第一次按下的時候就會調用onTouchEvent
方法,接着就會調用按下時的位置,擷取到x、y坐标并設定到文本框裡,設定完以後整個方法就麼有了,擷取完後就從記憶體中消失了,按下時的x、y的值也就消失了。onTouchEvent
- 是以在方法外定義x、y,因為擷取到的是小數,要定義為
類型float
- 移動的位置就不需要擷取了,隻要按下和松開的位置進行對比就可以判斷是上、下、左、右的哪個滑動了
- 右滑
- 下滑
- 把上述代碼進行如下修改
- 在
方法外定義x、y的位置onTouchEvent
//記錄按下手指的位置
float startX = 0;
float startY = 0;
-
方法裡的onTouchEvent
判斷作出如下修改if
if (action == TouchEvent.PRIMARY_POINT_DOWN){
MmiPoint point = touchEvent.getPointerPosition(0);
//x、y表示按下時手指的位置
startX = point.getX();
startY = point.getY();
}else if (action == TouchEvent.POINT_MOVE){
//移動的位置就不需要擷取了,隻要按下和松開的位置進行對比就可以判斷是上、下、左、右的哪個滑動了
}else if (action == TouchEvent.PRIMARY_POINT_UP){
//松開或擡起
MmiPoint point = touchEvent.getPointerPosition(0);
//x、y表示按下時手指的位置
float endX = point.getX();
float endY = point.getY();
//拿着按下時的位置跟松開時手指的位置進行比對
if (endX > startX){
text1.setText("右滑");
}else if (endX < startX){
text1.setText("左滑");
}else if (endY > startY){
text1.setText("下滑");
}else if (endY < startY) {
text1.setText("上滑");
}
- 按下後滑鼠從左往右移動,然後松開
- 按下後滑鼠從右往左移動,然後松開
- 按下後滑鼠從上往下移動,然後松開
- 按下後滑鼠從下往上移動,然後松開
- 此時還有一個明顯的bug,那就是當滑鼠從最最左邊上面的點到最右邊下面的點,既有下滑也有右滑
5. 滑動事件bug處理
- 當我們滑動的時候,滑的不直,滑的有點斜
- 斜着滑,可以對Y變化的範圍(斜的幅度)做一個規定,假設變化為100,如果你滑的時候變化了超過了100,那就認為這是一個無效的滑動,如果沒有超過,才認為這是一個有效的滑動
- 解決bug:
添加個絕對值,防止兩者大小相減出現複數
if (endX > startX && Math.abs(endY - startY) < 100){
text1.setText("右滑");
}else if (endX < startX && Math.abs(endY - startY) < 100){
text1.setText("左滑");
}else if (endY > startY && Math.abs(endX - startX) < 100){
text1.setText("下滑");
}else if (endY < startY && Math.abs(endX - startX) < 100) {
text1.setText("上滑");
}
- 運作,當斜的幅度超過
時,就會認為這是個無效的滑動,就不會顯示這個滑動的動作100
- 但運作斜的幅度不超過
,就會顯示正确的滑動效果100
6. onTouchEvent方法的傳回值
- 如果為
,表示所有的動作都會觸發目前方法并執行對應的代碼true
-
,表示隻有一個動作會觸發目前方法并執行對應的代碼,後續的動作就不會觸發目前方法false
- 滑動事件的三個動作:按下——>移動——>松開,當為
時,這三個動作都會執行true
方法并執行下面對應的代碼。為onTouchEvent
時,隻有按下這個動作會觸發false
方法并執行下面對應的代碼onTouchEvent
7. 驗證onTouchEvent方法的傳回值對滑動事件三個動作的影響
- 上述代碼不變,
方法改動如下:onTouchEvent
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
count++;
int action = touchEvent.getAction();
if (action == TouchEvent.PRIMARY_POINT_DOWN){
text1.setText("按下");
}else if (action == TouchEvent.POINT_MOVE){
text1.setText("移動");
}else if (action == TouchEvent.PRIMARY_POINT_UP){
text1.setText("松開");
}
//如果為true,表示所有的動作都會觸發目前方法并執行對應的代碼
//如果為false,表示隻有一個動作會觸發目前方法并執行對應的代碼,後續的動作就不會觸發目前方法了
return false;
}
- 運作後,當按下後再移動、松開。顯示的文本依賴不變,說明傳回值為
,隻有按下這個動作會觸發false
方法并執行下面對應的代碼,移動、松開都不會執行onTouchEvent
方法。onTouchEvent
- 把上面的傳回值改為
,運作後。發現文本顯示的值都會随着按下、移動、松開的動作進行變化。true
- 是以滑動事件一般都寫
。true