HarmonyOS實戰—滑動事件的坐標和返回值
Table of Contents
1. 滑動事件獲取手指位置
2. 獲取按下時手指的位置(坐標)
3. 實現案例:把按下、移動、松開的位置分別設置到文本框當中
4. 根據手指的位置來確定是上、下、左、右哪個滑動
5. 滑動事件bug處理
6. onTouchEvent方法的返回值
7. 驗證onTouchEvent方法的返回值對滑動事件三個動作的影響
1. 滑動事件獲取手指位置
- 滑動事件的三個動作:
- 獲取手指的位置就涉及到坐標的概念,通過獲取到 x、y、z就可以缺任意一個點的位置
- 手機中的坐標:
- 除了 x、y軸,還有z軸,在鴻蒙手機當中,完整的坐標如下,是一個立體的三維體系,但平時z軸用的非常少,一般情況只需考慮x、y軸就行了。
- 結合滑動事件的三個動作和坐標來分析滑動
2. 獲取按下時手指的位置(坐標)
獲取的這些數據其實都被鴻蒙操作系統封裝到TouchEvent這個動作對象當中,通過動作去調用getPointerPosition 方法,需要傳遞一個值。鴻蒙系統支持多手指的操作,比如:可以用兩個手指對圖片進行放大或縮小,所以在getPointerPosition需要傳遞一個索引,一個手指操作傳遞的值為0,表示要獲取的是第一個手指的位置,他的位置也是封裝成一個對象,再用坐標對象分別獲取到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方法外面去,因為如果沒有移動外面去,當第一次按下的時候就會調用onTouchEvent方法,接著就會調用按下時的位置,獲取到x、y坐標并設置到文本框里,設置完以后整個方法就么有了,獲取完后就從內存中消失了,按下時的x、y的值也就消失了。
所以在方法外定義x、y,因為獲取到的是小數,要定義為float類型
移動的位置就不需要獲取了,只要按下和松開的位置進行對比就可以判斷是上、下、左、右的哪個滑動了
- 右滑
- 下滑
- 把上述代碼進行如下修改
- 在onTouchEvent方法外定義x、y的位置
- //記錄按下手指的位置
- 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。
















































