注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

早衰男的巢

大音希声 道隐无名

 
 
 

日志

 
 

Android笔记: onTouch事件机制备忘一则  

2014-04-17 13:14:36|  分类: android笔记 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
live writer一直配置不了网易博客,搞到写日志的激情都大减。博客技术问题没人管可能是下一个被收皮的好产品,唏嘘。话题扯回来。

这两天遇到的状况是这样。某个界面上要求加入一些点触时的酷炫动态交互效果。应要求写了个自定义的View控件,里面用TouchEvent实现了相应的动画效果。 源码大概是这样的

MyView.java

public class MyView extends View{

public MyView(Context context) {
this(context, null);
}
public MyView (Context context, AttributeSet attrs) {
super(context, attrs);  

……//一些特效实现的细节这里略掉
}


@Override

protected void onDraw(Canvas canvas) {

……//绘画动画过程略

}


@Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN: //手指按下

……//业务略
Log.d(Util.TAG,"playStatus DOWN:"+playStatus);
this.invalidate(); //启动特效
return true; //若返回false,消失且接收不到下次事件
case MotionEvent.ACTION_UP: //手指抬起
……//业务略
Log.d(Util.TAG,"playStatus UP:"+playStatus);
return true;
}
return super.onTouchEvent(event);
}

}


layout.xml部分

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/silver" >

<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:orientation="vertical" >

<com.myapp.test.MyView
android:id="@+id/myView1"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_margin="5dp"
android:background="@drawable/img_button1" />
</LinearLayout>


嗯,手指点上去,狂拽酷炫屌炸天的效果出来了。
然后一想...不对!MyView控件自顾自的酷玩不行,我还要在Activity上实现一些对应功能。

MyActivity.java

//前后内容略

private MyView myView;

myView = findViewById(R.id.myView1);

myView.setOnTouchListener(new OnTouchListener(){

@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d(Util.TAG,"activity touch down"); //业务逻辑略了
return true;
case MotionEvent.ACTION_UP:
Log.d(Util.TAG,"activity touch down"); //业务逻辑略
return true;
}
return false;
}
})
;
心想这样便ok, 一运行...傻了!activity的OnTouchListener 把MyView 的 onTouchEvent给覆写了。
之后开始研究各种的旁门左道,用interface 自定义一个listener啦,用handler的Message啦..各种碰壁各种闪退崩溃
花了一个上午,才回来看看这个Touch有没有办法传递或super下去... 不行的..再看...哦,找到一个好东西,原来在调用onTouch之前,还有一个 分派的事件被触发 dispatchTouchEvent 。原本用来解决当多个重叠时点击事件是否被拦截或传递用。这里正好..给我分别错开触发业务和特效。

于是把MyView的 onTouchEvent部分替换为

@Override
public boolean dispatchTouchEvent(MotionEvent event) { //onTouchEvent改成前置分发,就不怕后面被中断了,我TM太机智了!

switch(event.getAction()) {
case MotionEvent.ACTION_DOWN: //手指按下
Log.d(Util.TAG,"playStatus DOWN:"+playStatus); //特效实现略
this.invalidate();
break; //这里不能直接return t/f 否则会造成接收不到事件
case MotionEvent.ACTION_UP: //手指抬起
Log.d(Util.TAG,"playStatus UP:"+playStatus);//特效实现略
break;
}
return super.dispatchTouchEvent(event);
}

Activity不改,再运行!okay~收工~

P.S. 啰嗦多句,看到备注在 dispatchTouchEvent 中 我没有直接return boolean值,而是super.dispatchTouchEvent(event)。这样才能pass给ontouch继续处理,不然会被拦截掉。

** Handler接收 + Message 的方式其实是可行的,但要实现 MyView和Activiy共用一个Handler,这样得代码被切得太零碎,东一块西一块的不喜欢..放弃这种方式实现..
  评论这张
 
阅读(697)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018