View和ViewGroup,Activity事件分发机制(5)

> View和ViewGroup

-- 事件传递的顺序:Activity -> ViewGroup -> View

-- ViewGroup的相关事件有三个:onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent;onClickListener
View的相关事件只有两个:dispatchTouchEvent、onTouchEvent。onClickListener

-- View体系的绘制流程是从ViewRootImpl的performTraversals方法开始的;
View的测量大小流程:performMeasure –> measure –> onMeasure等方法;
View的测量位置流程:performLayout –> layout –> onLayout等方法;

View的绘制流程:performDraw-> draw-> onDraw等方法;

--  ((ViewGroup)getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0)这种方式获取Activity所设置的View。这个mDecor显然就是getWindow().getDecorView()返回的View,而我们通过setContentView设置的View是它的一个子View。

    dispatchTouchEvent (Activity) ->是否超出Activity所属的Window边界 (Activity) -> superDispatchTouchEvent (Window abstract class) -> superDispatchTouchEvent(PhoneWindow) -> superDispatchTouchEvent(DecorView) -> dispatchTouchEvent(ViewGroup FrameLayout)。

> Android事件分发机制

-- Android事件分发机制主要由“事件分发”—>“事件拦截”—>“事件响应”这三步来进行逻辑控制的。
1. 事件分发:public boolean dispatchTouchEvent(MotionEvent ev)
 当监听到有触发事件时,首先由Activity进行捕获,然后事件就进入事件分发的流程。Activity本身没有事件拦截,从而将事件传递给最外层的View的dispatchTouchEvent(MotionEvent ev)方法,该方法将对事件进行分发。
 return true : View消费所有事件。
 return false :停止分发,交由上层控件的onTouchEvent方法进行消费,如果本层控件是Activity,那么事件将被系统消费、处理。
super.dispatchTouchEvent(ev): 将事件交由本层的事件拦截onInterceptTouchEvent方法处理。

2. 事件拦截:public boolean onInterceptTouchEvent(MotionEvent ev)
 return true: 对事件拦截,交由本层的onTouchEvent进行处理。
 return false: 不拦截,分发到子View,由子View的dispatchTouchEvent方法处理。
 super.onInterceptTouchEvent(ev):默认表示事件拦截,交由本层的onTouchEvent进行处理。

3. 事件响应:public boolean onTouchEvent(MotionEvent ev)
 return true: 表示onTouchEvent处理完事件后消费了此次事件。
 return false: 不响应事件,不断的传递给上层的onTouchEvent方法处理,直到某个View的onTouchEvent返回true,则认为该事件被消费。如果到最顶层View还是返回false,那么该事件不消费,将交由Activity的onTouchEvent进行处理。
 return: super.onTouchEvent,不响应事件,结果与return返回false一样。

-- Android的分发机制:
 1.ViewGroup默认不拦截任何事件。
 2.点击事件的分发过程如下:dispatchTouchEvent—>onTouchListener的OnTouch方法—>onTouchEvent—>onClickListener的onClick方法。从而也可以看出onTouch优先于onClick执行。
 3.子View可以通过使用getParent().requestDisallowInterceptTouchEvent(true),阻止ViewGroup对其MOVE或UP事件进行拦截。
 4.一个点击事件产生后,传递过程是:Activity—>Window—>View。顶级View接受到事件后,就会按照上面的规则去分发事件。

> View.java,ViewGroup.java

-- View.java
public boolean dispatchTouchEvent(MotionEvent event)
public boolean onTouchEvent(MotionEvent event) 
 public class TestButton extends Button {

    public TestButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.i("TestButton", "dispatchTouchEvent    action = " + event.getAction());
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("TestButton", "onTouchEvent    action = " + event.getAction());
        return super.onTouchEvent(event);
    }
}

-- ViewGroup.java
public boolean dispatchTouchEvent(MotionEvent event)
public boolean onTouchEvent(MotionEvent event) 
public boolean onInterceptTouchEvent(MotionEvent event)
 public class TestLinearLayout extends LinearLayout {

    public TestLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d("TestLinerLayout", "onInterceptTouchEvent    action = " + ev.getAction());
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d("TestLinerLayout", "dispatchTouchEvent    action = " + ev.getAction());
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("TestLinerLayout", "onTouchEvent    action = " + event.getAction());
        return super.onTouchEvent(event);
    }
}

> Activity事件分发
public class MainActivity extends Activity {
    private RTButton button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          System.out.println("Activity---dispatchTouchEvent---DOWN");
          break;
        case MotionEvent.ACTION_MOVE:
              System.out.println("Activity---dispatchTouchEvent---MOVE");
          break;
        case MotionEvent.ACTION_UP:
          System.out.println("Activity---dispatchTouchEvent---UP");
          break;
        default:
          break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          System.out.println("Activity---onTouchEvent---DOWN");
          break;
        case MotionEvent.ACTION_MOVE:
          System.out.println("Activity---onTouchEvent---MOVE");
          break;
        case MotionEvent.ACTION_UP:
          System.out.println("Activity---onTouchEvent---UP");
          break;
        default:
          break;
        }
        return super.onTouchEvent(event);
    }
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.d("MainActivity", "onTouch    action = "+event.getAction() + v);
        return false;
    }

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值