Android Touch事件传递机制 一: OnTouch,OnItemClick(监听器),dispatchTouchEvent(伪生命周期)
ViewGroup
View
Activity dispatchTouchEvent
有
有
有 onInterceptTouchEvent
有
无
无 onTouchEvent
有
有
有
例子零: 只有OnTouch和OnItemClick
actualListView.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "DOWN",
Toast.LENGTH_SHORT).show();
return false; //这儿是true,下面是false,onItemClick会走 case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "UP",
Toast.LENGTH_SHORT).show();
return true; //上面随意,只要这个地方返回true,onItemClick就不会走
}
return false;
}
});
actualListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(MainActivity.this, "setOnClickListener",
Toast.LENGTH_SHORT).show();
} });
例子一: 只有OnTouch和OnItemClick
actualListView.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "DOWN",
Toast.LENGTH_SHORT).show();
break; case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "UP",
Toast.LENGTH_SHORT).show();
break;
}
return false; //返回false之后
}
});
actualListView.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "setOnClickListener", Toast.LENGTH_SHORT).show();
}
});
先走ACTION_DOWN,ACTION_UP,最后走onItemClick。
例子二:只有OnTouch和OnItemClick
actualListView.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "DOWN",
Toast.LENGTH_SHORT).show();
break; case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "UP",
Toast.LENGTH_SHORT).show();
break;
}
return true; //返回true之后
}
});
actualListView.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "setOnClickListener", Toast.LENGTH_SHORT).show();
}
});
先走ACTION_DOWN,ACTION_UP, onItemClick不走
例子三:只有OnTouch和OnItemClick和dispatchTouchEvent
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "dispatch DOWN",
Toast.LENGTH_SHORT).show();
break; case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "dispatch UP",
Toast.LENGTH_SHORT).show();
break;
} return super.dispatchTouchEvent(ev);
}
actualListView.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "DOWN",
Toast.LENGTH_SHORT).show();
break; case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "UP",
Toast.LENGTH_SHORT).show();
break;
}
return false; //返回false之后
}
});
actualListView.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "setOnClickListener", Toast.LENGTH_SHORT).show();
}
});
先走dispatchTouchEvent的ACTION_DOWN------------>OnTouch的ACTION_DOWN------------->dispatchTouchEvent的ACTION_UP
----------------->OnTouch的ACTION_UP----------------->onItemClick
例子四:只有OnTouch和OnItemClick和dispatchTouchEvent
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "dispatch DOWN",
Toast.LENGTH_SHORT).show();
break; case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "dispatch UP",
Toast.LENGTH_SHORT).show();
break;
} return super.dispatchTouchEvent(ev);
}
actualListView.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "DOWN",
Toast.LENGTH_SHORT).show();
break; case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "UP",
Toast.LENGTH_SHORT).show();
break;
}
return true; //返回true之后
}
});
actualListView.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "setOnClickListener", Toast.LENGTH_SHORT).show();
}
});
先走dispatchTouchEvent的ACTION_DOWN------------>OnTouch的ACTION_DOWN------------->dispatchTouchEvent的ACTION_UP
----------------->OnTouch的ACTION_UP
例子五:只有OnTouch和OnItemClick和dispatchTouchEvent
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "dispatch DOWN",
Toast.LENGTH_SHORT).show();
return true; //这儿无论是true还是false,都会导致OnTouch和OnItemClick不走,因为没有下面的super来分发事件在activity中的操作 case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "dispatch UP",
Toast.LENGTH_SHORT).show();
return true; //这儿无论是true还是false,都会导致OnTouch和OnItemClick不走,因为没有下面的super来分发事件在activity中的操作
}
return super.dispatchTouchEvent(ev);
}
actualListView.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "DOWN",
Toast.LENGTH_SHORT).show();
break; case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "UP",
Toast.LENGTH_SHORT).show();
break;
}
return false; //返回false之后
}
});
actualListView.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "setOnClickListener", Toast.LENGTH_SHORT).show();
}
});
先走dispatchTouchEvent的ACTION_DOWN---------------------->dispatchTouchEvent的ACTION_UP
例子六:有OnTouch和OnItemClick 和 dispatchTouchEvent和onTouchEvent
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "dispatch DOWN",
Toast.LENGTH_SHORT).show();
break;
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "dispatch UP",
Toast.LENGTH_SHORT).show();
break;
} return super.dispatchTouchEvent(ev);
} @Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(MainActivity.this, "EveUP",
Toast.LENGTH_SHORT).show();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "Event DOWN",
Toast.LENGTH_SHORT).show();
return true;
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "Event UP",
Toast.LENGTH_SHORT).show();
return true;
}
return super.onTouchEvent(event);
} Button button = (Button) findViewById(R.id.go_shopping);//这儿改为CLICKABLE的imageview结果一样
button.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "DOWN",
Toast.LENGTH_SHORT).show();
return false; //这儿是true,下面是false,onItemClick会走 case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "UP",
Toast.LENGTH_SHORT).show();
return false; //上面随意,只要这个地方返回true,onItemClick就不会走
}
return false;
}
});
button.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "setOnClickListener",
Toast.LENGTH_SHORT).show();
}
});
先走dispatchTouchEvent的ACTION_DOWN------------>OnTouch的ACTION_DOWN------------->dispatchTouchEvent的ACTION_UP
----------------->OnTouch的ACTION_UP------------>OnClickListener
activity的伪生命周期onTouchEvent没有走,是因为button的onTouchEvent把事件消费了,
例子七:有OnTouch和OnItemClick 和 dispatchTouchEvent和onTouchEvent
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "dispatch DOWN",
Toast.LENGTH_SHORT).show();
break;
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "dispatch UP",
Toast.LENGTH_SHORT).show();
break;
} return super.dispatchTouchEvent(ev);
} @Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(MainActivity.this, "EveUP",
Toast.LENGTH_SHORT).show();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "Event DOWN",
Toast.LENGTH_SHORT).show();
return true;
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "Event UP",
Toast.LENGTH_SHORT).show();
return true;
}
return super.onTouchEvent(event);
} Button button = (Button) findViewById(R.id.go_shopping); //这儿改为imageview结果一样
button.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "DOWN",
Toast.LENGTH_SHORT).show();
return false; //这儿是true,下面是false,onItemClick会走 case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "UP",
Toast.LENGTH_SHORT).show();
return true; //上面随意,只要这个地方返回true,onItemClick就不会走
}
return false;
}
});
button.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "setOnClickListener",
Toast.LENGTH_SHORT).show();
}
});
先走dispatchTouchEvent的ACTION_DOWN------------>OnTouch的ACTION_DOWN------------->dispatchTouchEvent的ACTION_UP
----------------->OnTouch的ACTION_UP
button的OnClickListener没走,是因为onTouch 在ACTION_UP中返回true,把事件给消费了,导致button的onTouchEvent没走,连带的button的OnClick
也没有走。
activity的伪生命周期onTouchEvent没有走,是因为button的onTouch把事件消费了。
例子八:有 dispatchTouchEvent和onTouchEvent
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "dispatch DOWN",
Toast.LENGTH_SHORT).show();
break;
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "dispatch UP",
Toast.LENGTH_SHORT).show();
break;
} return super.dispatchTouchEvent(ev);
} @Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(MainActivity.this, "EveUP",
Toast.LENGTH_SHORT).show();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(MainActivity.this, "Event DOWN",
Toast.LENGTH_SHORT).show();
return true;
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "Event UP",
Toast.LENGTH_SHORT).show();
return true;
}
return super.onTouchEvent(event);
} Button button = (Button) findViewById(R.id.go_shopping);
//不给button设置ontouch和onclick
先走dispatchTouchEvent的ACTION_DOWN----------------->dispatchTouchEvent的ACTION_UP
activity的伪生命周期onTouchEvent没有走,是因为button的dispatchTouchEvent------>onTouchEvent把事件消费了。即使没有ontouch,事件也会被
button给消费掉
viewgroup(listview)和view(button)一样,其onTouchEvent会把事件给消费了,和view(imageview)不一样。
要想activity的伪生命周期onTouchEvent可以走的话,可以把button改为imageview,因为imageview不是“可按的CLICKABLE”,所以会imageview的onTouchEvent会return个false,不会消费掉这个事件
会先走dispatchTouchEvent的ACTION_DOWN------------>onTouchEvent的ACTION_DOWN------------->dispatchTouchEvent的ACTION_UP
----------------->onTouchEvent的ACTION_UP
点击一个ViewGrounp中的Button,事件的传递
Activity的dispatchTouchEvent(返回true或false都会导致事件不会分发,要返回super)----->ViewGrounp的dispatchTouchEvent-------->ViewGrounp的onInterceptTouchEvent()(返回false不拦截)--------->Button的dispatchTouchEvent------------->Button的setOnTouchListener(在up/down时如果返回false)------------->Button的onTouchEvent默认返回true消费事件(imageview默认返回false,事件会向上传/第二个事件的传递看我的另一个文章Android Touch事件传递机制 二)------>Button的setOnClickListener(在onTouchEvent中的up时调用)
Activity的dispatchTouchEvent(返回true或false都会导致事件不会分发,要返回super)----->ViewGrounp的dispatchTouchEvent-------->ViewGrounp的onInterceptTouchEvent()(返回false不拦截)--------->Button的dispatchTouchEvent------------->Button的setOnTouchListener(在up/down时如果返回true)消费事件结束
Activity的dispatchTouchEvent(返回true或false都会导致事件不会分发,要返回super)----->ViewGrounp的dispatchTouchEvent-------->ViewGrounp的onInterceptTouchEvent()(返回false不拦截)--------->Button的dispatchTouchEvent(Button的setOnTouchListener为null)------------->Button的onTouchEvent默认返回true----------->Button的setOnClickListener(在onTouchEvent中的up时调用)
最新文章
- Service Provider Interface
- linux启动和关闭
- JS——全选与反选
- WPF之MVVM(Step4)&mdash;&mdash;使用Prism(2)
- hdu 5492 Find a path(dp+少量数学)2015 ACM/ICPC Asia Regional Hefei Online
- GPS(2)关于位置的3个示例,实时获取GPS定位数据,求两个经纬点距离,邻近某个区域圆时警告
- SQlSERVER生成唯一编号
- 快速构建Windows 8风格应用8-贴靠视图
- Python logging模块使用记录
- 更改maven中央仓库
- Chrome控制台使用详解
- Python总结(一)
- python第十二天 生成器,迭代器,内置函数
- Java之Date Time API (Java 8 新特性)
- 功能的显著性分析——GO Enrichment Analysis
- 力扣(LeetCode)191. 位1的个数
- C# 简单反射实现winform左侧树形导航,右侧切换内容
- Task.FromResult应用场景举例
- centos7和Ubuntu上的关机需要手动关闭电源的问题
- 查询测试程序中的selectOne和selectList函数
热门文章
- 解读sencha touch移动框架的核心架构(一)
- 轻量级前端MVVM框架avalon - 初步接触
- Java (JVM) Memory Model – Memory Management in Java
- 配置React Native环境
- Linux NFS 服务部署
- 用纯JS做俄罗斯方块 - 简要思路介绍(1)
- 【406错误】 The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request ";accept"; headers.
- 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式
- javascript异步编程的前世今生,从onclick到await/async
- 记dynamic的一个小坑 -- RuntimeBinderException:“object”未包含“xxx”的定义