onTouch和android ontoucheventt的区别

[android]&setOnTouchEvent&设置返回值为true&和&false的区别
今天在做自定义的可选文本的 TextView 类时,用到了 View 类的
setOnTouchListener(OnTouchListener l)事件监听,在构造 OnTouchListener
对象时需要重写 onTouch(...)方法,这个方法的返回值是布尔类型,
& 刚开始我按默认给定的返回值 false运行,发现只能监听到这个 view
的“按下”事件,“移动”和“抬起”都不能够监听到;于是把返回值改为了 true,就都监听到了。
& 但是随后又遇到了一个问题,那就是:点击其他组件后,再点击这个 view
的时候获取不到焦点!也就是click事件不响应了。我猜想一定是受到了 onTouch 方法的影响,查资料发现:
设为true 和 false的效果是有区别的:
setOnTouchListener 单独使用的时候返回值需要为true,这样才能保证移动的时候能后获取相应的监
听,而非一次监听(即每次只有一个按下的事件)
setOnTouchListener 和 setOnClickListener 同时使用时,onTouch 的返回值要设为
false,这样既可
&&&&&&以保证按下移动抬起事件可以被监听,并且点击事件也会被监听。
于是,我又对这个 view 设置了setOnClickListener(虽然重写的方法体中什么也没写),并将onTouch
的返回值要设为 了false,结果就 既监听到了Touch 也能监听到 click 事件了,可以重获焦点了!
-----------------------------------------------------------------------------------------------
tv.setOnTouchListener(new OnTouchListener() {
&&&&&&&&&&&&
&&&&public
boolean onTouch(View v, MotionEvent event) {
TODO Auto-generated method stub
&&&&&&&&&&
&&&&switch
(event.getAction()) {
case MotionEvent.ACTION_DOWN:
&&&&&&...&&&
&&&&&&case
MotionEvent.ACTION_MOVE:
MotionEvent.ACTION_UP:&&&&&
&&&&return
// (或return& true)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。| 漏洞检测 |
| 隐藏捆绑 |
Android View的onTouchEvent和OnTouch区别
还是以自定义的TestButton为例。 我们可以通过重写onTouchEvent方法来处理诸如down move up的消息: public class TestButton extends Button {public TestButton(Context context) {super(context);// TODO Auto-generated constructor stub}public TestButt
还是以自定义的TestButton为例。
我们可以通过重写onTouchEvent方法来处理诸如down move up的消息:
public class TestButton extends Button {
public TestButton(Context context) {
super(context);
// TODO Auto-generated constructor stub
public TestButton(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
// TODO Auto-generated constructor stub
public boolean onTouchEvent(MotionEvent event) {
boolean value = super.onTouchEvent(event);
System.out.println("super.onTouchEvent: " + value+ " event: " + event.getAction());
}也可以通过实现OnTouchListener的接口,然后设置TestButton的onTouchListener可以达到同样的目的
class OnTouchListenerTest implements View.OnTouchListener{
public boolean onTouch(View v, MotionEvent event) {
TestButton b = (TestButton)findViewById(R.id.button);
OnTouchListenerTest listener = new OnTouchListenerTest();
b.setOnTouchListener(listener);但上述两种监听有什么区别呢?
先看一下Android源码中对于View中dispatchTouchEvent的实现:
public boolean dispatchTouchEvent(MotionEvent event){
if(onFilterTouchEventForSecurity(event)){
ListenerInfo li = mListenerI
if(li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
if(onTouchEvent(event)){
可以看到onTouchListener的接口的优先级是要高于onTouchEvent的,假若onTouchListener中的onTouch方法返回true,
表示此次事件已经被消费了,那onTouchEvent是接收不到消息的。
因为Button的performClick是利用onTouchEvent实现,假若onTouchEvent没有被调用到,那么Button的Click事件也无法响应。
综合来讲:
onTouchListener的onTouch方法优先级比onTouchEvent高,会先触发。
假如onTouch方法返回false会接着触发onTouchEvent,反之onTouchEvent方法不会被调用。
内置诸如click事件的实现等等都基于onTouchEvent,假如onTouch返回true,这些事件将不会被触发。
(责任编辑:幽灵学院)
------分隔线----------------------------
场长挪用千万公款赴(澳门赌博网站) 坚信小赌怡情,大赌伤身 中国江西网讯 王倩、记...
最近携程开源了一套动态加载的框架,总的来说,该框架和OpenAtlas还是有一定的相似之...
apktool 反编译APK 使用apktool d ,默认会生成和APK文件名同名的文件夹,里面会存放反...
话说一个乞丐在看一个程序员写程序,程序员遇到一个问题怎么都解决不了,这时乞丐说这...
本节引言: 最近一段时间因为工作上的事以及面试等等,耽误了博客的更新,这里道歉下~...
美团的下拉刷新分为三个状态: 第一个状态为下拉刷新状态(pull to refresh),在这个状...
admin@1744.cc
工作日:9:00-21:00
周 六:9:00-18:00
&&扫一扫关注幽灵学院
广告服务:QQ:1.onTouch方法:
onTouch方法是View的 OnTouchListener接口中定义的方法。
当一个View绑定了OnTouchLister后,当有touch事件触发时,就会调用onTouch方法。(当把手放到View上后,onTouch方法被一遍一遍地被调用),这个方法有返回值 false 和true
2.onTouchEvent方法:
onTouchEvent方法是override 的Activity的方法。
覆写了Activity的onTouchEvent方法后,当屏幕有touch事件时,此方法就会别调用。
(当把手放到Activity上时,onTouchEvent方法就会一遍一遍地被调用)
3.touch事件的传递:
在一个Activity里面放一个TextView的实例tv,绑定onTouchClickListener监听器,并且这个tv的属性设定为 fill_parent,占满整个屏幕。
在这种情况下,当手放到屏幕上的时候,首先会是tv响应touch事件,执行onTouch方法。
如果onTouch返回值为true,
表示这个touch事件被onTouch方法处理完毕,不会把touch事件再传递给Activity,也就是说onTouchEvent方法不会被调用。
(当把手放到屏幕上后,onTouch方法被一遍一遍地被调用)
如果onTouch的返回值是false,
表示这个touch事件没有被tv完全处理,onTouch返回以后,touch事件被传递给Activity,onTouchEvent方法被调用。
(当把手放到屏幕上后,onTouch方法调用一次后,onTouchEvent方法就会一遍一遍地被调用)
何谓一遍一遍调用?
在onTouch 和onTouchEvent方法中,传入的肯定是event对象,一般都是执行switch判断语句,来判断传入的event对象是什么, 使用event.getAction()方法。
阅读(...) 评论()简单游戏 快乐生活
全国门店目录
您当前的位置:
>> >> >>正文
OnTouchEvent()&触屏事件
编辑:kezz
发布时间: 13:17:41
&&&&&& 一: 前言:& && & 各位童鞋肯定都知道在模拟器中,我们的鼠标当点击一次模拟器屏幕然后释放,先触发 ACTION_DOWN 然后 ACTION_UP ;如果是在屏幕上移动那么才会触发 ACTION_MOVE 的动作;OK,很对。但是你要知道,这只是模拟器!& && & 二:真机与模拟器的区别:& && & 当我们的小用户(说到用户我就想起“我叫MT”中的暗夜男那句经典台词:亲爱的客户,我是嫩爹!)咳咳,回到话题;当我们的用户在玩我们的游戏的时候,尤其是RPG这种类型的,用户肯定需要会长时间的去触屏按我们的虚拟按键,比如我们会在屏幕上画上一个虚拟方向盘类似这样子~那么其实 ACTION_MOVE 这个事件会被Android一直在响应!& && &&&三: 为什么会一直响应 ACTION_MOVE 这个动作呢? 如果用户没有移动手指而是静止不动也会一直响应?& && & 原因有两点:第一点是因为,Android 对于触屏事件很敏感!第二点:虽然我们的手指感觉是静止没有移动,其实事实不是如此!当我们的手指触摸到手机屏幕上之后,感觉静止没动,其实手指在不停的微颤抖震动。java代码:package eoe.
import android.app.A import android.os.B import android.util.L import android.view.MotionE import android.view.W import android.view.WindowM /** * @author Himi */ public class MainActivity extends Activity { private O private final int TIME = 50;//备注1 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); object = new Object(); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Log.v("Himi", "ACTION_DOWN"); } else if (event.getAction() == MotionEvent.ACTION_UP) { Log.v("Himi", "ACTION_UP"); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { Log.v("Himi", "ACTION_MOVE"); } synchronized (object) {//备注2 try { object.wait(TIME); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //这里一定要返回true!} }
关注安卓中文网官方微信
扫描左侧二维码即可添加安卓中文网官方微信
您也可以在微信上搜索“安卓中文网”或“anzhuozww”,获取更多数码资讯
24小时热点从源码角度带你分析 Android View 事件分发 dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程(一)
关于Android View 事件分发过程的文章网络上可以搜到一把大,这里贴一篇代码性的文章,作者也是个牛人:Android事件分发机制完全解析,带你从的角度彻底理解(上)。
虽然讲的很好,但是看完之后还是感觉有那么点一知半解,于是自己花了点时间从源码研究android 触摸事件分发流程,以下内容仅仅个人理解,如有差错希望指出。
我们先从一个例子看起,先重写一个MyButton 继承Button,代码如下:
public class MyButton extends Button {
public MyButton(Context context) {
super(context);
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
MyLog.e(&dispatchTouchEvent====MyButton=====ACTION_DOWN&);
case MotionEvent.ACTION_MOVE:
MyLog.e(&dispatchTouchEvent====MyButton=====ACTION_MOVE&);
case MotionEvent.ACTION_UP:
MyLog.e(&dispatchTouchEvent====MyButton=====ACTION_UP&);
return super.dispatchTouchEvent(event);
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
MyLog.e(&onTouchEvent====MyButton=====ACTION_DOWN&);
case MotionEvent.ACTION_MOVE:
MyLog.e(&onTouchEvent====MyButton=====ACTION_MOVE&);
case MotionEvent.ACTION_UP:
MyLog.e(&onTouchEvent====MyButton=====ACTION_UP&);
return super.onTouchEvent(event);
布局文件如下:
测试Activity如下:
public class MainActivity extends ActionBarActivity {
private Button myB
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton = (Button) findViewById(R.id.myButton);
myButton.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
MyLog.e(&onTouch====MyButton=====ACTION_DOWN&);
case MotionEvent.ACTION_MOVE:
MyLog.e(&onTouch====MyButton=====ACTION_MOVE&);
case MotionEvent.ACTION_UP:
MyLog.e(&onTouch====MyButton=====ACTION_UP&);
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MyLog.e(&onClick====MyButton=====onClick&);
点击测试按钮,打印结果如下:
我们从打印结果可以直观看到,点击Button按钮事件分发过程如下 dispatchTouchEvent----&onTouch----&onTouchEvent-----&onClick。并且如果仔细的你会发现,都是在ACTION_UP事件之后才触发onClick点击事件,为什么会是这样??现在我们不得而知。我们仅仅是从打印结果推测事件分发的结论,现在我们从源码分析下这个事件分发流程为什么是这样子。
事件分发都是从dispatchTouchEvent方法开始的,那么我们这里是重写了dispatchTouchEvent方法,并且最后也调用了父类的super.dispatchTouchEvent(event)方法。那么我们看看父类中的方法到底做了什么??点击进入父类的dispatchTouchEvent方法,发现此方法在View类中找到,其实也不奇怪,所有控件的父类都是View。这里我贴出最新源码如下:
public boolean dispatchTouchEvent(MotionEvent event) {
boolean result =
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
final int actionMasked = event.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Defensive cleanup for new gesture
stopNestedScroll();
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerI
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
if (!result && onTouchEvent(event)) {
if (!result && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
// Clean up after nested scrolls if this is
// also cancel it if we tried an ACTION_DOWN but we didn't want the rest
// of the gesture.
if (actionMasked == MotionEvent.ACTION_UP ||
actionMasked == MotionEvent.ACTION_CANCEL ||
(actionMasked == MotionEvent.ACTION_DOWN && !result)) {
stopNestedScroll();
忽略其他无关代码,我们直接看17--25行。第17行的if判断关键在于li.mOnTouchListener.onTouch(this, event) 的返回值,这个接口回调就是我们外面写的myButton.setOnTouchListener事件(Button 的onTouch事件),在MainActivity代码里,我们setOnTouchListener返回的值是false,所以在源码中我们可以看到 17行的条件不成立,那么条件不成立,result=false;因此,源码的第23行if 判断第一个条件成立,继续执行第二个条件,也就是onTouchEvent。我们跳到这个方法里看看里面干啥了?看如下代码:
public boolean onTouchEvent(MotionEvent event) {
if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
// take focus if we don't have it already and we should in
// touch mode.
boolean focusTaken =
if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
focusTaken = requestFocus();
if (prepressed) {
// The button is being released before we actually
// showed it as pressed.
Make it show the pressed
// state now (before scheduling the click) to ensure
// the user sees it.
setPressed(true, x, y);
if (!mHasPerformedLongPress) {
// This is a tap, so remove the longpress check
removeLongPressCallback();
// Only perform take click actions if we were in the pressed state
if (!focusTaken) {
// Use a Runnable and post this rather than calling
// performClick directly. This lets other visual state
// of the view update before click actions start.
if (mPerformClick == null) {
mPerformClick = new PerformClick();
if (!post(mPerformClick)) {
performClick();
if (mUnsetPressedState == null) {
mUnsetPressedState = new UnsetPressedState();
if (prepressed) {
postDelayed(mUnsetPressedState,
ViewConfiguration.getPressedStateDuration());
} else if (!post(mUnsetPressedState)) {
// If the post failed, unpress right now
mUnsetPressedState.run();
removeTapCallback();
我们看看这里边都做了些什么,忽略其他,我们直接看37行的 performClick(); 方法,跳进去继续看,(注意:这里的performClick方法是在ACTION_UP手势里边执行的哦!!!)
public boolean performClick() {
final ListenerInfo li = mListenerI
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
看见没??第6行 li.mOnClickListener.onClick(this); 这个接口回调就是我们Button的 onClick事件。到此为止,我们从源码分析了Button事件分发过程
结论:dispatchTouchEvent----&onTouch----&onTouchEvent-----&onClick。并且如果仔细的你会发现,是在所有ACTION_UP事件之后才触发onClick点击事件。
现在我们来看看其他情况:当onTouch返回为true,打印结果如下:
惊奇的发现,竟然没有执行onClick事件是吧????如果你仔细上面的文章,估计你知道为什么了吧?还是跟大家一起分析一下吧:源码如下:
public boolean dispatchTouchEvent(MotionEvent event) {
boolean result =
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
final int actionMasked = event.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Defensive cleanup for new gesture
stopNestedScroll();
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerI
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
if (!result && onTouchEvent(event)) {
if (!result && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
// Clean up after nested scrolls if this is
// also cancel it if we tried an ACTION_DOWN but we didn't want the rest
// of the gesture.
if (actionMasked == MotionEvent.ACTION_UP ||
actionMasked == MotionEvent.ACTION_CANCEL ||
(actionMasked == MotionEvent.ACTION_DOWN && !result)) {
stopNestedScroll();
从第17行可以看出,条件成立,result=true;那么第23行if条件根本不会执行第二个判断,那么就不会执行onTouchEvent方法,也就不会调用 onClick的接口,因此Button 不会执行setOnClickListener中的onClick事件。
给个简单的流程图如下
因此,事件分发之间的关系是:dispatchTouchEvent方法中线执行 onTouch接口回调,然后根据onTouch方法的返回值判断是否执行onTouchEvent方法,onTouchEvent方法中执行了onClick接口回调。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'}

我要回帖

更多关于 安卓ontouchevent 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信