Foreword
Android distribution in passing on a touch event is something very worthy of study. You have seen the introduction of a sliding function of the ListView, ListView not listen to your finger fingers summoned rolled; do not know why Button set the onClick and onTouch, which who will respond first; perhaps you will have to ask onTouch and onTouchEvent What is the difference, how to use? Everything here, as long as you understand the event distribution mechanism, you will find that this is not the interpretation of the thing!
RELATED Touch event
1, public boolean dispatchTouchEvent (MotionEvent EV) ---- event distribution method, the distribution of the Event call
2, public boolean onInterceptTouchEvent (MotionEvent EV) ---- event interceptor method, called intercepts Event
3, public boolean onTouchEvent (MotionEvent Event) ---- incident response method, called Event processing
The event has a class above
1, Activity class (Activity and various subclasses)
dispatchTouchEvent()、onTouchEvent()
2、ViewGroup类(LinearLayout、FrameLayout、ListView等.....)
dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent()
3, View class (Button, TextView ..... etc.)
dispatchTouchEvent()、onTouchEvent()
PS: requires special attention to the fact that additional ViewGroup have onInterceptTouchEvent () method, two other methods for these three types have in common.
The method uses simple analytical
We can find that the return of these three methods are boolean type, in fact, they are processed to determine the direction of the next pass through the return value.
1, dispatchTouchEvent () - used to distribute event
Top-down event which will in turn distribute to the root element of the inner sub-element, or terminated until reaching the innermost element, the method also uses a tunneling distributed. In which calls onInterceptTouchEvent () and onTouchEvent (), generally will not go rewrite.
Return false not to intercept continue to distribute down, returns true if to intercept the matter is not distributed to the lower element, returns false by default in dispatchTouchEvent () method.
2, onInterceptTouchEvent () - used to intercept events
This method returns false realize that not intercept events, Touch event is passed down to his son in ViewGroup View source code.
If we override this method and return to their true, the event will be intercepted, and is currently ViewGroup processing, call onTouchEvent class () method.
3, onTouchEvent () - used to handle events
Returns true indicates that the View can handle the event, the event will terminate passed up (pass to its parent View)
That they can not handle returns false, the event is passed to put the parent onTouchEvent View () method to handle
Practical exercise
Well, the basics finished, the above things do not understand it does not matter, now looked good to keep your eyes open, because the following event distribution mechanism began to explain with an example Touch, we believe we can make a better understanding of the distribution mechanism.
In this case, we need to rewrite the four categories:
1, the boss -> MyActivity
2, Manager -> FrameLayout
3, the head -> LineaLayout
4, employees -> TextView
Software interface is as follows:
[ Examples put forward a plain open at the beginning ]
1, common sense, leadership will be assigned the task down, once the following people to do things well, would not bring a subsequent task to do the following people, can only personally do, if they do No, I can only tell superiors can not complete the task, his superiors would repeat the process.
2. In addition, the leadership has the right to intercept mission, to hide the subordinate task, and direct yourself to do, if you do not, can not complete the task can only report to their superiors.
Process demo
[1], we assume that the lack of staff capacity, that is, the TextView onTouchEvent () method is set to return false, indicating that it can not consume the event.
Event delivery process:
[2], we assume that employees can handle the event, that is, the TextView onTouchEvent () method returns true Set to indicate that it can handle the event.
Event delivery process:
[3], we assume that the lack of staff and head of the capabilities that TextView and LinearLayout of onTouch () returns false, but the manager resolved the problem, namely FrameLayout of onTouch () returns true
Event delivery process:
[4] We assume that the head of the event distributed to him when the decision not to intercept them below employees, is onInterceptTouchEvent () returns true, and he also successfully completed the task, namely onTouchEvent () return value It is true.
Event delivery process:
Be Summary
1, it is clear that these processes is dispatchTouchEvent () deal, but only if we do not fully re-implement this method, that is, the need to ensure return super.dispatchTouchEvent (ev); determining the parent class has to be called. These events will deliver a top-down layer by layer, until it passed to the bottom of the View element, this time will call the View of onTouchEvent () method to handle the event; return true to indicate the event has been successfully processed If it returns false if not successfully processed the event, the event will be passed up layer by layer, to the upper layer View of onTouchEvent () method of treatment, and so on until a View successfully processed the event, or to top View still processing return false to abandon processing of the event, the event disappeared.
2、如果在事件向下传递的过程中,被中途拦截,也就是View的onInterceptTouchEvent()方法返回true,那么该事件将停止向下传递,并交给该层的onTouchEvent()方法处理,无论处理成功与否,底层View将再也不会接收到该事件。PS:若处理失败,则会交由上层View的onTouchEvent()方法处理。
3、dispatchTouchEvent()具有记忆的功能,如果第一次事件向下传递到某View,它把事件继续传递交给它的子View,它会记录该事件是否被它下面的View给处理成功了,(怎么能知道呢?如果该事件会再次被向上传递到我这里来由我的onTouchEvent()来处理,那就说明下面的View都没能成功处理该事件);当第二次事件向下传递到该View,该View的dispatchTouchEvent()方法机会判断,若上次的事件由下面的view成功处理了,那么这次的事件就继续交给下面的来处理,若上次的事件没有被下面的处理成功,那么这次的事件就不会向下传递了,该View直接调用自己的onTouchEvent()方法来处理该事件。
4、记忆功能的信息只在一系列事件完成之前有效,如从ACTION_DOWN事件开始,直到后续事件ACTION_MOVE,ACTION_UP结束后,“记忆”的信息就会清除。也就是说如果某View处理ACTION_DOWN事件失败了(onTouchEvent()返回false),那么后续的ACTION_MOVE,ACTION_UP等事件就不会再传递到该View了,由其父View自己来处理。在下一次发生ACTION_DOWN事件的时候,还是会传递到该View的。
附带代码
1、MyActivity
public class MyActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("test", "【老板】下达任务:" + Util.actionToString(ev.getAction()) + ",找个人帮我完成,任务往下分发。"); return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { boolean relust = false; Log.i("test", "【老板】完成任务:" + Util.actionToString(event.getAction()) + ",【经理】太差劲了,以后不再找你干活了,我自来搞定!是否解决:" + Util.canDoTaskTop(relust)); return relust; } }
2、MyFrameLayout:
public class MyFrameLayout extends FrameLayout {
public MyFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("test", "【经理】下达任务:" + Util.actionToString(ev.getAction()) + ",找个人帮我完成,任务往下分发。"); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean relust = false; Log.i("test", "【经理】是否拦截任务:" + Util.actionToString(ev.getAction()) + ",拦下来?" + relust); return relust; } @Override public boolean onTouchEvent(MotionEvent event) { boolean relust = true; Log.i("test", "【经理】完成任务:" + Util.actionToString(event.getAction()) + ",【组长】太差劲了,以后不再找你干活了,我自来搞定!是否解决:" + Util.canDoTask(relust)); return relust; } }
3、MyLinearLayout
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("test", "【组长】下达任务:" + Util.actionToString(ev.getAction()) + ",找个人帮我完成,任务往下分发。"); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean relust = true; Log.i("test", "【组长】是否拦截任务:" + Util.actionToString(ev.getAction()) + ",拦下来?" + relust); return relust; } @Override public boolean onTouchEvent(MotionEvent event) { boolean relust = true; Log.i("test", "【组长】完成任务:" + Util.actionToString(event.getAction()) + ",【员工】太差劲了,以后不再找你干活了,我自来搞定!是否解决:" + Util.canDoTask(relust)); return relust; } }
4、MyTextView
public class MyTextView extends TextView {
public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.i("test", "【员工】下达任务:" + Util.actionToString(event.getAction()) + ",我没手下了,唉~自己干吧"); return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { boolean relust = false; Log.i("test", "【员工】完成任务:" + Util.actionToString(event.getAction()) + ",【员工】现在只能靠自己了!是否解决:" + Util.canDoTask(relust)); return relust; } }
5、Util(工具类)
public class Util {
public static String actionToString(int action){ String result = null; switch(action){ case MotionEvent.ACTION_DOWN: result = "ACTION_DOWN"; break; case MotionEvent.ACTION_MOVE: result = "ACTION_MOVE"; break; case MotionEvent.ACTION_UP: result = "ACTION_UP"; break; } return result; } public static String canDoTask(boolean can){ String result = null; if(can){ result = "完美解决该任务!"; } else{ result = "这活搞不定,交给老大完成吧。"; } return result; } public static String canDoTaskTop(boolean can){ String result = null; if(can){ result = "完美解决该任务!"; } else{ result = "这活搞不定,放弃该任务。"; } return result; } }
转自https://www.cnblogs.com/net168/p/4165970.html