转载本专栏每一篇博客请注明转载出处地址,尊重原创。此博客转载链接地址:点击打开链接   http://blog.csdn.net/qq_32059827/article/details/52577017

之前对这篇文章写的不够详细,觉得有必要在对这篇文章完善一下。本文使用Log方式分析,不涉及源码。log方式更直观易懂一些。

首先,View的几个基本的继承关系:

本博客案例的图层:

要实现上边这个图层结构,需要自定义View,并在里面加入log打印,只有自定义View才能测试log情况。我们这里自定义View只需要重写几个分发事件方法即可。如下:

MainActivity:

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} /**
* activity的
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "Activity+分发+dispatchTouchEvent");
return super.dispatchTouchEvent(event);
} /**
* activity的
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "Activity+处理+onTouchEvent");
return super.onTouchEvent(event);
}
}

由于Activity只有dispatchTouchEvent和onTouchEvent两个方法。因此重写之
然后,新建两个容器类型的View:

自定义View,第一个容器View----类型属于ViewGroup:(LinearLayout就属于容器类型的View,因此继承自它。继承其他容器View也可以比如RelativeLayout也可以的)

public class ViewGroupOne extends LinearLayout {

	public ViewGroupOne(Context context, AttributeSet attrs) {
super(context, attrs);
} public ViewGroupOne(Context context) {
super(context);
} /**
* 分发事件
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+分发+dispatchTouchEvent");
return super.dispatchTouchEvent(event);
//return true;
//return false;
} /**
* 拦截事件
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+拦截+onInterceptTouchEvent");
return super.onInterceptTouchEvent(event);
// return true;
// return false;
} /**
* 处理事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+处理+onTouchEvent");
return super.onTouchEvent(event);
// return true;
} }

自定义View,第二个容器View----属于ViewGroup:

public class ViewGroupTwo extends LinearLayout {

	public ViewGroupTwo(Context context, AttributeSet attrs) {
super(context, attrs);
} public ViewGroupTwo(Context context) {
super(context);
} @Override
public boolean dispatchTouchEvent(MotionEvent event) {
//getParent().requestDisallowInterceptTouchEvent(true);//本质上不让父组件的dispatchtouchevent生效
ActionUtiles.processEvent(event, "ViewGroupTwo+分发+dispatchTouchEvent");
return super.dispatchTouchEvent(event);
// return false;
// return true;
} @Override
public boolean onInterceptTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+拦截+onInterceptTouchEvent");
return super.onInterceptTouchEvent(event);
// return true;
} @Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+处理+onTouchEvent");
return super.onTouchEvent(event);
} }

加入一个没有子组件的View,类型类似TextView:

public class MyTextView extends TextView {

	public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
} public MyTextView(Context context) {
super(context);
} @Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "MyTextView+分发+dispatchTouchEvent");
return super.dispatchTouchEvent(event);
} @Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "MyTextView+处理+onTouchEvent");
return super.onTouchEvent(event);//回传机制
//return true;//事件消费,不回传
//return false;//和默认效果一样,回传机制
}
}

因为每个类,每个事件方法都需要写如下代码:

switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i(name, "按下ACTION_DOWN");
            break;
        case MotionEvent.ACTION_CANCEL:
            Log.d(name, "取消ACTION_CANCEL");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.e(name, "移动ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.w(name, "松开ACTION_UP");
            break;
        case MotionEvent.ACTION_OUTSIDE:
            Log.v(name, "点击外面ACTION_OUTSIDE");
            break;

default:
            break;
        }

功能大家都一样,因此抽取一个Utis类来处理这个方法即可,如下:

public class ActionUtiles {
/**
*
* @param event处理的事件
* @param name组件的名称哪个类触发打印的)
*/
public static void processEvent(MotionEvent event,String name){
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i(name, "按下ACTION_DOWN");
break;
case MotionEvent.ACTION_CANCEL:
Log.d(name, "取消ACTION_CANCEL");
break;
case MotionEvent.ACTION_MOVE:
Log.e(name, "移动ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.w(name, "松开ACTION_UP");
break;
case MotionEvent.ACTION_OUTSIDE:
Log.v(name, "点击外面ACTION_OUTSIDE");
break; default:
break;
}
}
}

为了测试不同事件的打印情况,log使用不同的日志级别进行区分。

接着写一个复合上边图层的布局:

<com.example.event.ViewGroupOne
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"
android:background="#ff0000"
android:orientation="vertical" > <com.example.event.ViewGroupTwo
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#00ff00" > <com.example.event.MyTextView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#0000ff" >
</com.example.event.MyTextView>
</com.example.event.ViewGroupTwo> </com.example.event.ViewGroupOne>

注意:记得自定义View需要写类的全称。

好了,废话不多说,直接运行程序说话。通多点击手机屏幕。对所有的可能情况全部罗列如下:

一、默认情况,对生成的事件方法返回值什么也不做。返回值都是默认情况:

事件1:点击红色位置。看log输出

按下:可以看到,整个事件是Activity先得到事件,调用它的dispatchTouchEvent分发事件,Activity返回值默认传递给ViewGroupOne,调用ViewGroupOne的dispatchTouchEvent方法,此时这个返回值默认return super.dispatchTouchEvent(event);默认的时候它会把事件传递给自己的onInterceptTouchEvent(MotionEvent event)拦截事件看自己是否需要拦截这个事件,但是由于它的返回值也是默return super.onInterceptTouchEvent(event);认,即没做拦截;事件继续传递,传递给自己的onTouchEvent(MotionEvent event)看自己是否处理这个事件;  自己的onTouchEvent(MotionEvent event)处理方法被调用,但是返回值也是默认,return super.onTouchEvent(event);自己并不处理事件。这样事件到了最里层的View也没有被消费,事件开始回传,回传给父容器Activity的onTouchEvent(MotionEvent event) ,Activity也是默认返回值,表示不做任何处理。整个过程事件都没有做处理和拦截,事件作废。松开后:看一下松开事件:由Activity的dispatchTouchEvent开始分发事件自己返回值是默认情况,把事件直接分发给自己的onTouchEvent(MotionEvent event)方法处理事件,自己返回值是默认情况,事件作废。 整个事件过程,并没有任何地方要处理事件, 由up事件log日志,也可以看到:最后松手时的事件,已经与ViewGroupOne没有任何关系。

事件2:点击绿色区域l。看log输出:

这里就会显而易见了。多了ViewGroupTwo,就多往下传递一层,最里面这层没做处理,最后还是回传回来。一直回传到activity事件全部消失

事件3:点击蓝色区域:

这个肯定在意料之中,不用解释也很清楚为何打印此log了。

二、增加处理:

处理1:蓝色区域,MyTextView修改如下代码:

@Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "MyTextView+处理+onTouchEvent"); return true;//事件消费,不回传
}

此时要重新运行程序了再点击蓝色区域,看log:

MyTextView的onTouchEvent(MotionEvent event)返回true的意思是,事件由我来处理。它处理了事件,就不可能出现回传了,出现这种log也是顺理成章了。再看UP事件与分发拦截是一致的。最后在MyTextView中消失。这个时候可以对比一了,一都是默认,可以称之为狭义的回传机制,而二的处理1:我们可以称之为狭义的拦截机制,每一次的往下分发,又可称为狭义的传递机制(称之为狭义,可能逼格略高些,是因为不能代表全部,却也不失一般性;最起码拦截与回传分发大致是什么很清楚了)。那接着就细致开来,从狭义走到广义。

处理2:蓝色区域,MyTextView修改如下代码:

@Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "MyTextView+处理+onTouchEvent"); return false;//和默认效果一样,回传机制
}

再运行,打印看log:

和默认效果是一样的。回看默认解析。

处理3:蓝色区域,MyTextView的dispatchTouchEvent方法修改如下代码:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "MyTextView+分发+dispatchTouchEvent"); return true; }

看log:

MyTextView的dispatchTouchEvent(MotionEvent event)返回值为true,表示不再分发事件也可以说是拦截事件。此时MyTextView的onTouchEvent方法不会被调用,既然是拦截了事件也不会回传。

处理4:蓝色区域,MyTextView的dispatchTouchEvent方法修改如下代码:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "MyTextView+分发+dispatchTouchEvent");
return false;
}

看log输出:

MyTextView的dispatchTouchEvent(MotionEvent event)返回值为false,表示我自己MyTextView不做事件的分发,那么,我自己的后续方法(onTouchEvent方法)不再被调用执行。直接回传给父控件的onTouchEvent处理方法处理事件,父控件都是默认情况。事件一直回传,直到Activity,事件消失。

说明:上边都是针对蓝色区域点击;这是因为,只有点击了蓝色位置,事件才有可能传递到MyTextView,点击其他位置根本不会调MyTextView的任何方法。

第一次总结:

TextView(没有子组件类型)

dispatchTouchEvent(MotionEvent event)

return true; //不再分发事件,表示拦截事件,拦截掉不会回传,事件在此消失
            return false;//表示不做分发事件,事件不被拦截,回传给父控件的处理方法

return super.onTouchEvent() ;//事件传递机制,传递给自己的onTouchEvent方法。

onTouchEvent()
            return true; //自己处理消费掉事件,事件消费不再回传
            return false;或者 return super.onTouchEvent() ;//效果一样,事件回传给父组件

处理5:点击绿色区域,ViewGroupTwo的dispatchTouchEvent方法做如下修改:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+分发+dispatchTouchEvent");
return true;
}

看log:

由于ViewGroupTwo的dispatchTouchEvent方法返回值为true,则事件被拦截,不会往下传递同时也不会回传。事件在此消失。

处理6:点击绿色区域,ViewGroupTwo的dispatchTouchEvent方法做如下修改:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+分发+dispatchTouchEvent");
return false;
}

看log:

由于ViewGroupTwo的dispatchTouchEvent方法返回值为false,这跟MyTextView的dispatchTouchEvent返回值为false时候原因是一样的。这个时候,表示我自己不做事件分发,自己的onInterceptTouchEvent方法不会被调用(由于MyTextView没有onInterceptTouchEvent,它是onTouchEvent方法不会被调用),做回传机制。回传给父控件的处理方法,调用父控件的 onTouchEvent方法。父控件默认值,一直传递到Activity,最终事件消失。

说明:这里点击绿色区域和蓝色区域效果是一样的,确切的说没必要点击蓝色区域测试。因为,dispatchTouchEvent并不会直接影响子控件的调用情况。他只决定自己的onInterceptTouchEvent方法是否会被调用。

处理6:点击蓝色区域,ViewGroupTwo的onInterceptTouchEvent方法做如下修改:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+拦截+onInterceptTouchEvent");
return true;
}

看log:

由于ViewGroupTwo的onInterceptTouchEvent方法返回值为true,表示我要拦截事件,而且事件交给我自己的处理事件,看处理不处理,如果不处理,则回传机制,回传事件给父控件的处理方法,看是否处理事件。

说明:这里点击绿色区域和蓝色区域效果是一样的,虽然ViewGroupTwo的onInterceptTouchEvent方法可能与孩子控件的dispatchTouchEvent方法有影响,但是由于自己的onInterceptTouchEvent的返回值为true,表示拦截事件,那么直接调用自己的onTouchEvent方法,而不会去调用孩子的dispatchTouchEvent方法。因而,点击蓝色绿色位置其实效果是一样的。

处理7:点击蓝色区域,ViewGroupTwo的onInterceptTouchEvent方法做如下修改:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+拦截+onInterceptTouchEvent"); return false;
}

可以看到,此时跟默认return super.onInterceptTouchEvent(event);效果是一摸一样的。

说明:这个时候点击绿色区域就不行了。因为点击绿色区域,看不到事件传递给孩子组件的过程。

处理8:点击蓝色区域,ViewGroupTwo的onTouchEvent方法做如下修改:

注意:这个方法想要执行,前提是在ViewGroupTwo的onInterceptTouchEvent方法返回true的时候,或者孩子组件都不做事件处理的时候。因为,自己的onInterceptTouchEvent为true拦截后调用自己的onTouchEvent方法是否做处理。孩子组件如果都是默认,为回传机制,最终肯定会回到自己的onTouchEvent处理事件。

@Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+处理+onTouchEvent"); return true; }

看log:

ViewGroupTwo的onTouchEvent方法返回了true,表示调用了我之后,我就做处理事件。由于ViewGroupTwo的onInterceptTouchEvent返回值为默认或者false,不会立即调用自己的onTouchEvent处理事件, 我们按下的时候,事件还是继续分发给孩子组件,孩子组件没处理事件,就会回传给自己的onTouchEvent,问自己是否处理?true,处理事件,事件在此消失。同样地,这里点击绿色区域也没法测试,原因同上。我们可以看一下UP事件,UP事件直观的告诉我们,事件是由自己处理的。

测试ViewGroupTwo的onTouchEvent方法返回了false的时候,跟默认的return super.onTouchEvent(event);效果是一样的。这个可以自行测试。

处理9:混合处理。点击蓝色区域,ViewGroupTwo的onTouchEvent方法和onInterceptTouchEvent方法做如下修改:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+拦截+onInterceptTouchEvent");
return true;
} @Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupTwo+处理+onTouchEvent");
return true;
}

看log日志:

相信这是在意料之中的事情了吧?由于我自己的onInterceptTouchEvent方法返回值true,表示我要做拦截事件,那么孩子的任何方法肯定不会被调用了,不会得到事件。直接调用自己的处理方法onTouchEvent。问自己处理不处理?返回值为true,处理事件了,则事件终止,被自己消费掉。这个时候,点击绿色区域效果也是一样的,这是因为自己的onInterceptTouchEvent方法返回值true,孩子压根得不到点击事件。

第二次总结:

2,ViewGroup
      dispatchTouchEvent
            return true;//事件分发拦截、事件回传拦截。自己消费,不往下(子组件)(不分发)、不往上传递(不回传)
            return false;//事件拦截、事件回传。自己不处理,回传给父组件onTouchEvent方法处理
            return super.dis.....;//事件分发。问自己onInterceptTouchEvent是否拦截
                   问自己  >onInterceptTouchEvent
                                true:  肯定会调用自己onTouchEvent();看是否自己消费事件。但是可能会去孩子那里执行一下MotionEvent.ACTION_CANCEL:,给孩子打声招呼。
                                false 或  super: 两者效果相同,事件传递,默认往下传递,调用孩子组件的dispatchTouchEvent
                              
                                   onInterceptTouchEvent返回true时:问自己>onTouchEvent()
                                              true: 自己消费(不回传)
                                              false 或 super: 两者效果相同,继续回传,回传给父亲组件的onTouchEvent()

处理10:ViewGroupOne的dispatchTouchEvent方法做如下修改,点击任意区域:

	@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+分发+dispatchTouchEvent");
return true;
}

运行程序,点击蓝色位置看log:

其实你会发现。不管点击屏幕哪个位置,都打印这样的log

这是因为,ViewGroupOne的dispatchTouchEvent返回true了,相当于在ViewGroupOne的分发事件地方就拦截了事件(称之为拦截,也因为没有回传,从UP日志里也可以看出没有回传)。事件消失。

处理11:ViewGroupOne的dispatchTouchEvent方法做如下修改,点击任意位置:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+分发+dispatchTouchEvent"); return false;
}

返回false,表示自己的dispatchTouchEvent不做处理,即不做分发事件。做回传,回传给activity的onTouchEvent处理,最后事件消失。这里同样点击任意位置都是这个log,因为dispatchTouchEvent只有返回默认的时候,才会分发事件。

注意:ViewGroupOne的dispatchTouchEvent方法默认返回super.dispatchTouchEvent(event);的时候是要传递给自己的onInterceptTouchEvent方法的,问这个方式是否做拦截。上边其实已经不知不觉介绍了这个情况。此时可以总结,只有在ViewGroupOne的dispatchTouchEvent方法默认返回super.dispatchTouchEvent(event);的时候才会去调用自己的onInterceptTouchEvent(MotionEvent event) 拦截事件。其他都属于拦截事件,返回true的话甚至连回传机制都消失。

处理12:ViewGroupOne的onInterceptTouchEvent方法做如下修改,点击红色区域:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+拦截+onInterceptTouchEvent");
return true;
}

log情况

自己的onInterceptTouchEvent(MotionEvent event)拦截事件返回为true,表名自己要拦截,不向下传递。调用自己的onTouchEvent(MotionEvent event)问自己是否处理。由于自己默认不处理,又回传到activity事件消失。同样的,这里点击任何位置log日志都是如此。因为,我拦截事件,只允许事件调用自己的onTouchEvent方法问是否自己做处理,如果自己不作处理事件回传了,如果自己处理事件,事件就会消失。

处理13:ViewGroupOne的onInterceptTouchEvent(MotionEvent event)拦截事件返回false

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+拦截+onInterceptTouchEvent");
return false;
}

又是默认的机制。

处理14:ViewGroupOne的onTouchEvent做如下处理:

注意:这个方法想要执行,前提是在ViewGroupOne的onInterceptTouchEvent方法返回true的时候,或者孩子组件都不做事件处理的时候。因为,自己的onInterceptTouchEvent为true拦截后调用自己的onTouchEvent方法是否做处理。孩子组件如果都是默认,为回传机制,最终肯定会回到自己的onTouchEvent处理事件。

@Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+处理+onTouchEvent");
return true;
}

看log:

返回true。当孩子组件都做默认处理,事件会回传到自己的onTouchEvent方法。  自己处理事件,也就没了回传机制。事件在此消失。

处理15:ViewGroupOne的onTouchEvent返回为false。不用打印也可以清楚,与默认效果是一样的。

处理16:混合处理。ViewGroupOne的onTouchEvent和onInterceptTouchEvent做如下处理,点击蓝色区域:

	@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+拦截+onInterceptTouchEvent");
return true;
} @Override
public boolean onTouchEvent(MotionEvent event) {
ActionUtiles.processEvent(event, "ViewGroupOne+处理+onTouchEvent");
return true;
}

看log:

由于自己的onInterceptTouchEvent方法返回为true,表示我要处理事件,不再往下传递事件,调用自己的onTouchEvent方法,问自己是否处理,返回了true,说明自己处理事件。事件在此消费,事件消失。

对于ViewGroupTwo和ViewGroupOne总结部分是一摸一样的。就不再多赘述。最后,再用一张草图做一个收尾::

此草图虽然潦草,但是最能说明问题,基本包含了所有可能的情况。

对于拦截机制详细介绍就完毕了,但是除了上边这些情况外,还有许多的分支情况;但是大同小异,仔细分析一下,就能得出正确的结论。以后此专栏可能还会再次探讨类似问题,下一次讨论应该是直接通过源码来分析这个问题。

喜欢的话可以关注我博客,有问题大家一起交流。也可以动手微信扫描下方二维码查看更多安卓文章:

打开微信搜索公众号  Android程序员开发指南  或者手机扫描下方二维码 在公众号阅读更多Android文章。

微信公众号图片:

Android事件分发传递回传机制详解的更多相关文章

  1. 通俗理解Android事件分发与消费机制

    深入:Android Touch事件传递机制全面解析(从WMS到View树) 通俗理解Android事件分发与消费机制 说起Android滑动冲突,是个很常见的场景,比如SliddingMenu与Li ...

  2. Android事件分发和消费机制(转载)

    原文链接:http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html Android 中与 Touch 事件相关的方法包括:dispatc ...

  3. Android事件分发传递

    一.与触摸事件有关的几个方法 boolean dispatchTouchEvent(MotionEvent ev); 接收到触摸事件时,是否分发事件到下面的View 返回true:分发触摸事件 返回f ...

  4. Android开发——Android 6.0权限管理机制详解

    .Android 6.0运行时主动请求权限 3.1  检测和申请权限 下面的例子介绍上面列出的读写SD卡的使用例子,可以使用以下的方式解决: public boolean isGrantExterna ...

  5. Android事件分发详解(六)——ACTION_DOWN的消费验证

    MainActivity如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 3 ...

  6. Android事件分发与责任链模式

    一.责任链模式 责任链模式是一种行为模式,为请求创建一个接收者的对象链.这样就避免,一个请求链接多个接收者的情况.进行外部解耦.类似于单向链表结构. 优点: 1. 降低耦合度.它将请求的发送者和接收者 ...

  7. Android事件传递机制详解及最新源码分析——ViewGroup篇

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...

  8. Android 的事件传递机制,详解

    Android 的事件传递机制,详解 前两天和一个朋友聊天的时候.然后说到事件传递机制.然后让我说的时候,忽然发现说的不是非常清楚,事实上Android 的事件传递机制也是知道一些,可是感觉自己知道的 ...

  9. Android Touch事件传递机制详解 下

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38025165 资源下载:http://download.csdn.net/detail/yu ...

随机推荐

  1. ubuntu安装 tar.gz格式程序

    tar.gz(bz或bz2等) 一.安装1.打开一个SHELL,即终端2.用cd 命令进入源代码压缩包所在的目录3.根据压缩包类型解压缩文件(*代表压缩包名称)tar -zxvf ****.tar.g ...

  2. Centos常用命令之:文件与目录管理

    在centos中常用的文件与目录操作命令有: ◇chmod:修改文件或目录的权限 ◇mkdir:新建目录◇rmdir:删除目录◇rm:删除目录或文件◇cp:复制目录或文件◇mv:移动目录或文件 下面就 ...

  3. (MariaDB/MySQL)之DML(1):数据插入

    本文目录: 1.insert和replace插入数据 1.1 insert into values() 1.2 insert into set 1.3 insert into select_state ...

  4. Python获取会议部分的信息内容(不断完善中)

    这是一个用于获取物理师会议报告的简单爬虫,数据库表结构正在不断完善中 爬虫信息: # -*- coding:utf-8 -*- import urllib.request import pymysql ...

  5. 计蒜客NOIP模拟赛6 D1T1Diamond-square

    Diamond-square 算法是一种能够用于生成噪声的算法,现在我们考虑这个算法的一个变种. 你有一个 2^n\times 2^n2​n​​×2​n​​ 的网格,一共有 (2^n+1)^2(2​n ...

  6. BZOJ3684 大朋友和多叉树(多项式相关计算)

    设$f(x)$为树的生成函数,即$x^i$的系数为根节点权值为$i$的树的个数.不难得出$f(x)=\sum_{k\in D}f(x)^k+x$我们要求这个多项式的第$n$项,由拉格朗日反演可得$[x ...

  7. WebStorm 快捷键一览

    查找/代替 快捷键 说明 ctrl+shift+N 通过文件名快速查找工程内的文件(必记) ctrl+shift+alt+N 通过一个字符快速查找位置(必记) ctrl+F 在文件内快速查找代码 F3 ...

  8. Debugging TensorFlow models 调试 TensorFlow 模型

    Debugging TensorFlow models Symbolic nature of TensorFlow makes it relatively more difficult to debu ...

  9. Weblogic Exception in AppMerge flows' progression

    原因:经过分析是web.xml配置的问题,有些servlet上面配置了'display-name',这个weblogic是不支持的. 解决:在web.xml中把'display-name'删除掉,工程 ...

  10. requestAnimationFrame之缓动的应用

    之前需要使用的定时器的时,立马想到的是setInterval(),用着用着就成为习惯,并没有遇到什么不妥之处.习惯性的操作往往容易让一个人拒绝尝试一些其他的方法.现在的方法用得好好的,没事干啥找其他法 ...