`
zha_zi
  • 浏览: 584798 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

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 交互中值返回的问题

 

 

 

 

 

  • 大小: 106.1 KB
  • 大小: 22.9 KB
  • 大小: 139.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics