• onTouch事件试验(覆写onTouchEvent方法,同时设置onTouchListener)


    xml布局文件

    复制代码
    <</span>RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <</span>com.example.shijian.MyButton
            android:id="@+id/mybutton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="测试按钮"
            />
    
    </</span>RelativeLayout>
    
    复制代码

    自定义Button

    复制代码
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.Button;
    
    public class MyButton extends Button
    {
        public MyButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) 
        {
            super.onTouchEvent(event);
            int ea=event.getAction();  
    //           Log.i("TAG", "Touch:"+ea);
               switch(ea)
               {   
               case MotionEvent.ACTION_DOWN:
               {
                   Log.v("-MyButton-","------ACTION_DOWN-----");
                   return true;
    //               break;
               }
               case MotionEvent.ACTION_MOVE:
               {
                   Log.v("-MyButton-","------ACTION_MOVE-----");
                   break; 
               }
               case MotionEvent.ACTION_UP:
               {
                   Log.v("-MyButton-","------ACTION_UP-----"); 
                   break;
               }
        }return false; 
        
        }
    
    }
    
    复制代码

    MainActivity

    复制代码
    import android.os.Bundle;
    import android.app.Activity;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    
    public class MainActivity extends Activity{
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            MyButton mybutton = (MyButton)findViewById(R.id.mybutton);
            mybutton.setOnTouchListener(new OnTouchListener() {
                
                public boolean onTouch(View v, MotionEvent event) {
                    int ea=event.getAction();  
    //                   Log.i("TAG", "Touch:"+ea);
                       switch(ea)
                       {   
                       case MotionEvent.ACTION_DOWN:
                       {
                           Log.v("-onTouchListener-","------ACTION_DOWN-----");
                           break;
    //                       return true;
                       }
                       case MotionEvent.ACTION_MOVE:
                       {
                           Log.v("-onTouchListener-","------ACTION_MOVE-----");
                           break; 
    //                       return true;
                       }
                       case MotionEvent.ACTION_UP:
                       {
                           Log.v("-onTouchListener-","------ACTION_UP-----");
                           break;  
    //                       return true;
                       }
    
                }
                    return false;
                }
            });
        }
    
    }
    
    复制代码

    试验结果:

    一、首先固定MyButton中OnTouchEvent方法的所有返回都为false,设置OnTouchListener中:

    1)所有返回均为false:

         

    且Button的状态保持按下,即ACTION_UP没有执行 

     

    结论:这里用《疯狂android讲义》中的话:几乎所有基于回调的事件处理方法都有一个boolean类型的返回值,该返回值用于表示该处理方法是否能完全处理该事件:

      *如果处理事件的回调方法返回true,表明该处理方法已完全处理该事件,该事件不会传播出去。

      *如果处理事件的回调方法返回false,表明该处理方法并未完全处理该事件,该事件回传播出去。

          从Log输出可以看出,Listener最先触发了Touch事件,由于返回了false,事件传播了出去,所以MyButton的方法也触发了Touch事件。但是Touch事件是由ACTION_DOWN,ACTION_MOVE,ACTION_UP三个事件组成,为什么只打印了ACTION_DOWN呢?从图中的Button的状态来看,ACTION_UP确实没有执行,那么ACTION_MOVE呢?也没有执行,至于为什么,先卖个关子,会在后面解释清楚。

    2)ACTION_DOWN返回true,其他返回false:

    3)ACTION_DOWN和ACTION_MOVE返回true,其他返回false:

    4)ACTION_DOWN和ACTION_UP返回true,其他返回false:

    5)ACTION_MOVE和ACTION_UP返回true,其他返回false:

    结果与1)完全相同

    错误的结论:试验做到这里,我认为大概的结论应该是:

      Listener中的ACTION_DOWN若返回true,会发生

      1、ACTION_DOWN不会扩散出去,所以MyButton的OnTouchEvent方法不会触发ACTION_DOWN。

      2、Listener会接受后续的事件,所以Listener的Log会输出ACTION_MOVE和ACTION_UP。

      Listener中的ACTION_DOWN若返回false,会发生

      1、ACTION_DOWN会扩散出去,所以MyButton的OnTouchEvent方法会触发ACTION_DOWN。

      2、Listener不会接受后续的事件,所以Listener的Log不会输出ACTION_MOVE和ACTION_UP。

    但是,这些都是在——固定MyButton中OnTouchEvent方法的所有返回都为false——这一前提下,MyButton中OnTouchEvent的事件都是从Listener传递过来的,到底MyButton中OnTouchEvent方法的返回值对结果有没有影响呢?下面会有结果。

    6)所有返回true

    二、固定OnTouchListener的返回全为false,OnTouchEvent方法的返回值:

    1)ACTION_DOWN为true,其他全为false

    这个结果把之前的结论彻底推翻了。

    猜想:事件是否完全处理会影响到后续事件

         前面说过:*如果处理事件的回调方法返回true,表明该处理方法已完全处理该事件,该事件不会传播出去。

              *如果处理事件的回调方法返回false,表明该处理方法并未完全处理该事件,该事件回传播出去。

         但是传播出去后呢?当传播到下一个地方,又会进行判断,true就完全处理事件,不再传播,如果又是false呢?

         从ACTION_DOWN到ACTION_UP是一个连续的事件,这个连续事件中有ACTION_DOWN,ACTION_MOVE,ACTION_UP三个子事件。android的事件传播,是一种由下向上的冒泡传播,子控件不处理,就传到父控件。如果子事件被完全处理了(被消费了),则下一个子事件才能开始,否则,这个子事件将堵塞(例如所有的控件都不处理),后续的子事件将无法进入处理流程。

    三、OnTouchListener的ACTIONO_DOWN返回false,其他两个返回true,OnTouchEvent方法的ACTION_DOWN返回true,其他两个false:

    Button的状态:

    这一试验说明猜想成功了一次:

      由于OnTouchListener的ACTION_DOWN返回false,则不处理继续传播,到OnTouchEvent方法,返回true,表示消费了ACTION_DOWN事件,则ACTION_MOVE事件得以进入流程。

      OnTouchListener的ACTION_MOVE返回true,表示已经消费了ACTION_MOVE事件,则ACTION_UP事件得以进入流程。ACTION_MOVE事件不再传播,所以Log日志中,OnTouchEvent方法没有ACTION_MOVE输出。

      OnTouchListener的ACTION_UP返回true,表示已经消费了ACTION_UP事件,不再传播,所以Log日志中,OnTouchEvent方法没有ACTION_UP输出。

      由于OnTouchEvent方法仅仅执行了ACTION_DOWN,所以按钮的状态为“一直按下”。

    四、OnTouchListener的ACTIONO_UP返回true,其他两个返回false,OnTouchEvent方法的ACTION_DOWN返回true,其他两个false:

    Button的状态:

    看到了吗,将上个试验中OnTouchListener的ACTIONO_UP改为true,其他不变,按钮就恢复了,从Log也看到OnTouchEvent方法的ACTION_UP输出了。

  • 相关阅读:
    this:从JavaScript执行上下文视角讲this
    作用域链和闭包:代码中出现相同的变量,JavaScript引擎如何选择
    调用栈:为什么JavaScript代码会出现栈溢出
    变量提升:JavaScript代码是按顺序执行的吗
    uniapp
    uniapp
    uniapp
    uniapp
    js
    uniapp
  • 原文地址:https://www.cnblogs.com/laughingQing/p/4546175.html
Copyright © 2020-2023  润新知