android hybrid 中手勢如何處理

      hybrid 開發關於手勢的思考

       手勢非常總要,尤其是在app應用中,大量的app提供的右滑退出等功能培養了用戶習慣,所以我們在開發app的時候考慮到用戶體驗最好也要加入類似功能,但是具體到app 中或者是hybrid 下的webview 中,裏邊可很有可能需要處理橫向滾動處理,例如廣告,iscroll 控件,swiper 控件,等等也會需要橫向滑動手勢,如果做到兩個互不干擾,這是需要我們思考的一個問題,下圖就是一個帶有滑動切換廣告的banner ,

       



 

 

想解決這個問題,android 是否原始支持手勢退出,這個我研究一下好像沒有原生接口來支持,這樣一來我們就需要通過自己實現功能來處理滑動退出,參考了一下主流app 的操作習慣,但是我們需要考慮幾點,首要問題就是如何判斷用戶意圖是要退出當前頁面,通過對其他app和ios 一些應用的研究,當用戶從屏幕最左側作爲起始點滑動的時候是明顯具有退出意圖,所以,我們可以以此作爲核心參考依據,劃定一個滑動範圍作爲退出條件

1.滑動起始範圍

2.滑動速度

因爲android只有2d接口所以沒法判斷用戶按壓的力度,只能通過二維的手勢做簡單的判斷

這裏我們需要一個android skd 中一個 非常總要跟用戶點擊操作有關的接口

 

gestureDetector=new GestureDetector(GestureTest1Activity.this,onGestureListener);
/**
   @param e1 :起始移動點
   @param e2 :結束時的移動點
   @param velocityX x軸的移動速度
   @param velocityY y軸的移動速度

 

*/
public boolean onFling(android.view.MotionEvent e1, android.view.MotionEvent e2, float velocityX, float velocityY) {
System.out.println("onFling................"); 
			float x = e2.getX() - e1.getX();//滑動後的x值減去滑動前的x值 就是滑動的橫向水平距離(x)  
			float y = e2.getY() - e1.getY();//滑動後的y值減去滑動前的y值 就是滑動的縱向垂直距離(y)  
			float startX=e1.getX();
            
			 System.out.println(e1.getX()+"~~~~~~~~~~~~~~~~~~~~~~");
             //如果滑動的橫向距離大於100,表明是右滑了,那麼就執行下面的方法,可以是關閉當前的activity  
             if (x > 100&&startX<15) {  
                 doResult(RIGHT);  
                 Log.w("tag", "RIGHT>" + x);  
             }  
             //如果滑動的橫向距離大於100,表明是左滑了(因爲左滑爲負數,所以距離大於100就是x值小於-100)  
             if (x < -100) {  
                 Log.w("tag", "LEFT>" + x);  
                 doResult(LEFT);  
             }  
            
             return true;  
}

  GestureDetector 中有很多跟手勢相關的接口例如

 onFling 和點,滑動 有關,包含 touch start ,touch move ,touch end

 onDoubleTap 雙擊相關

 onScroll 滑動相關

  

 這樣我們就開發完成android native 下關於右滑退出的功能,這裏需要有個概念就是,activity 的事件

 分發機制。

 @Override
 public boolean dispatchTouchEvent(android.view.MotionEvent event) {
   // 在事件分發中把事件傳給手勢組件處理
   return gestureDetector.onTouchEvent(event);
 }

  當我們希望使用手勢相關的功能時候都要處理這個事件分發,重寫dispatchTouchEvent 把事件分發中的event 交給 gestureDetector 處理,

 這裏我簡單描述一下android的事件分發機制,android 的事件機制,與瀏覽器的事件有所不同

瀏覽器的事件傳播機制的核心是基於事件捕獲,和事件冒泡

android 的事件傳播機制是基於事件分發,分發器處理是在activity 上,

爲什麼需要這個事件機制處理,而且地位非常重要處於核心位置,我們深層思考不管是web,還是android 的view 都是一個視覺是二維,本質是三維的結構,如果view 本質都是二維的話,那麼事件機制就沒那麼重要了,因爲沒有父子關係也就沒有了事件傳播,獨立view 沒有相互關係也缺乏傳播的依據,我們在開發view 的時候不管是div 的嵌套關係,還是android RelativeLayout 都是父子嵌套的關係,



 

和android 的事件系統作對比



 

 

其實很相像。

 

所以我們只需要在activity 中做手勢處理,其他子組件做正常事件分發,這樣就能既滿足整個activity 的右滑手勢退出,而且webview 中的其他事件也能正常運行

 

 @Override
	 public boolean dispatchTouchEvent(android.view.MotionEvent event) {
		 // 調用父級會自動分發事件,否則字控件就沒有事件響應了,
		 	super.dispatchTouchEvent(event);
			switch (event.getAction()) {
				case android.view.MotionEvent.ACTION_SCROLL : 
					System.out.println("scroll................................");
					break;
				case android.view.MotionEvent.ACTION_DOWN: 
					System.out.println("ACTION_DOWN................................");
					break;
				case android.view.MotionEvent.ACTION_MOVE : 
					System.out.println("ACTION_MOVE................................");
					break;
				case android.view.MotionEvent.ACTION_UP : 
					System.out.println("ACTION_UP................................");
					break;
				default:
					break;
			}
			//wv.onTouchEvent(event); 
			return gestureDetector.onTouchEvent(event);
	 };

 注:在重寫dispatchTouchEvent 事件時候一定要調用 super.dispatchTouchEvent(event); 父類正常的事件分發,否則我們重寫的事件分發原始正常的分發過程就中斷了,

   我們也可以封裝成一個JavaScriptInterface 接口暴露給webview 的js 使用,可以讓用戶通過設置來選擇這個activity 是否支持手勢退出

  

 

 Hybird 開發中有很多地方需要處理

1.native 渲染和webview 中渲染不同步,大量的hybrid應用中會使用頭部native ,內容webview 導致很多設置會不生效

2.js 的緩存管理 例如localstorage 和緩存的js文件

3.跳轉路徑管理,傳參等問題

4.js hybrid 交互中值返回的問題

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章