Android 安卓事件分发

开发的过程中,会遇到很多很多的滑动冲突,当然,我们解决滑动冲突就会用到事件分发,由于网上的例子较多,你可能直接找一个工具类而不去考虑是怎么解决的,所以面试的时候一脸蒙蔽,在这里我也为大家讲解一下。

在这里给大家展示一个流程图,我在网上看到的,感觉画的不错。
这里写图片描述

  1. 可以看出事件分发是有三层事件处理,分别为Activity 、ViewGroup 、 View
  2. 事件处理的标志有 super、true、false(super是调用父类的实现)
  3. 由Activity的diapatchTouchEvent做分发,不管调用什么,都由ViewGrop层的dispatchTouchEvent来处理。
  4. dispatchTouchEvent和 onTouchEvent的框里有个【true—->消费】的字,表示的意思是如果方法返回true,那么代表事件就此消费,不会继续往别的地方传了,事件终止。

    给大家分享一张U型图,让大家更加的了解事件分发。

这里写图片描述
在下面总结一下我的理解。

  1. 如果我们没有对控件里面的方法进行重写或更改返回值,而直接用super调用父类的默认实现,那么整个事件流向应该是从Activity—->ViewGroup—>View 从上往下调用dispatchTouchEvent方法,一直到叶子节点(View)的时候,再由View—>ViewGroup—>Activity从下往上调用onTouchEvent方法。
  2. dispatchTouchEvent 和 onTouchEvent 一旦return true,事件就停止传递了(到达终点)(没有谁能再收到这个事件)。
  3. dispatchTouchEvent 和 onTouchEvent return false的时候事件都回传给父控件的onTouchEvent处理。

上面讲解的都是针对ACTION_DOWN的事件传递,ACTION_MOVE和ACTION_UP在传递的过程中并不是和ACTION_DOWN 一样,你在执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了。简单的说,就是当dispatchTouchEvent在进行事件分发的时候,只有前一个事件(如ACTION_DOWN)返回true,才会收到ACTION_MOVE和ACTION_UP的事件。

这里写图片描述
下面我写了一个小demo,你们可以在闲暇的时候,看看是怎么触发每一个方法的。

import android.content.Context;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class TouchView extends LinearLayout{
    private PointF pf=new PointF();
    private int disX=0;
    private int disY=0;
    public TouchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if(ev.getAction()==MotionEvent.ACTION_DOWN){
            Log.e("", "手指按下");
            pf.x=ev.getX();
            pf.y=ev.getY();
            Log.e("", "X:"+pf.x+"\tY:"+pf.y);
        }else if(ev.getAction()==MotionEvent.ACTION_POINTER_2_DOWN){
            Log.e("", "第二根手指按下");
            int x=(int) ev.getX();
            int y=(int) ev.getY();
            Log.e("", "第二根手指的坐标:X:"+x+"第二根手指的坐标:Y:"+y);
            disX=(int) Math.sqrt(Math.pow(ev.getX(0)-ev.getX(1), 2)+
                    Math.pow(ev.getY(0)-ev.getY(1), 2)
                    );
            Log.e("", "两手指间的距离"+disX);
        }else if(ev.getAction()==MotionEvent.ACTION_MOVE){
            Log.e("", "手指滑动");
            int x1=(int) ev.getX();
            int y1=(int) ev.getY();
            Log.e("", "手指滑动时当前的坐标:"+x1+"       "+y1);
        }else if(ev.getAction()==MotionEvent.ACTION_UP){
            Log.e("","手指抬起");
        }
        return super.dispatchTouchEvent(ev);
    }
}

MainActivity

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends Activity {
    private LinearLayout mLinear;
    private Button mBtn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        mLinear=(LinearLayout) findViewById(R.id.mLinear);
        mBtn=new Button(this);
        LinearLayout.LayoutParams lp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        mBtn.setLayoutParams(lp);
        mLinear.addView(mBtn);

        mBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                Log.e("","这是button按钮的点击事件" );
            }
        });
    }

}

最下面是布局文件:

<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"
    tools:context=".MainActivity" >
    <touchdemo.TouchView
        android:id="@+id/mLinear"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>

猜你喜欢

转载自blog.csdn.net/nazicsdn/article/details/81036088