Android event distribution (1)-View event distribution, androidview

Source: Internet
Author: User

Android event distribution (1)-View event distribution, androidview
MainActivity is as follows:

Package cc. cv; import android. OS. bundle; import android. view. motionEvent; import android. view. view; import android. view. view. onClickListener; import android. view. view. onTouchListener; import android. widget. button; import android. widget. imageView; import android. app. activity;/*** Demo Description: * View event distribution ** mainly involves dispatchTouchEvent (), onTouch (), and onTouchEvent () during View event distribution () ** true or false is returned for dispatchTouchEvent (). Whether to continue event distribution * onTouch () returns true or false, indicating whether the event is consumed * whether the event is mainly processed in onTouchEvent (). The event distribution starts from dispatchTouchEvent. * If the return value of the dispatchTouchEvent () method is true, the event distribution is resumed. If the return value is false, the event distribution is terminated. * Source Code: ** public boolean dispatchTouchEvent (MotionEvent event) {* if (mOnTouchListener! = Null & (mViewFlags & ENABLED_MASK) = ENABLED & mOnTouchListener. onTouch (this, event) {* return true; *} * return onTouchEvent (event); *} ** the return value of this method can be either of the following: ** 1 returns true if the condition is met. note the three judgments of the if condition. * 1.1 mOnTouchListener is not equal to null * 1.2 the current control is enable * 1.3 calls mOnTouchListener. the results returned by onTouch (this, event) * are not mentioned in the first two conditions. We mainly look at the third condition: * a series of ACTION_DOWN will be processed in onTouch (View v, MotionEvent event, ACTION_MOVE, ACTION_UP. * This on If the Touch () method returns true, the event is consumed. If the Touch () method returns false, the event is not consumed. * For example, if true is returned when ACTION_DOWN is processed, the ACTION_MOVE event will continue to be distributed. * For example, if true is returned when ACTION_MOVE is processed, the ACTION_UP event will continue to be distributed. * For example, if false is returned when ACTION_DOWN is processed, then the subsequent ACTION_MOVE and ACTION_UP will not continue to be distributed. * The ACTION_MOVE and ACTION_UP actions cannot be captured in the code. ** 2 if the if condition is not met, the execution continues and the onTouchEvent execution result is returned. * ** the differences and relationships between * onTouch (this, event) and onTouchEvent (event) can also be seen from the source code of the dispatchTouchEvent (): * 1. Call onTouch () first and then call o NTouchEvent () * 2 processes the Touch event in the onTouch () method, that is, when processing a series of ACTION_DOWN, ACTION_MOVE, ACTION_UP events * returns false, it indicates the event (each individual ACTION_DOWN, ACTION_MOVE, ACTION_UP is called an event, which does not mean that the three are linked together as an event. * onTouchEvent (event) is called only when it is not consumed ). * 3 in the ACTION_UP event in onTouchEvent, The delemclick () event is called to process the OnClick event !!!! * 4. Therefore, we can see that * 4.1 Touch events occur and are handled prior to Click events. Note that the onTouch () method returns false by default. * 4.2 only when onTouch () returns false (that is, the event is not consumed) Will onTouchEvent () be called. * 4.3 The ACTION_UP event in onTouchEvent () will call javasmclick () process OnClick events. * 5 refer to the onTouchEvent () source code below. Pay attention to the third if judgment. This if judgment is very important !!!!!!! * 5.1 In the if condition, determine whether the control is CLICKABLE or LONG_CLICKABLE ). * 5.2 if any of the CLICKABLE and LONG_CLICKABLE conditions is met, true will always be returned to the onTouchEvent () method * 5.3 if both CLICKABLE and LONG_CLICKABLE conditions are not met, false will be returned to onTouchEvent () method ** Note: * by default, the buttons are CLICKABLE and LONG_CLICKABLE, but ImageView * by default, CLICKABLE and LONG_CLICKABL are unavailable. ** therefore, the OnTouchListener and OnClickListener experiments with Button and ImageView are different. * notice again: The onTouch () method returns false by default. * 1 Button to perform an experiment and analyze dispatchTouchEvent (). * mOnTouchListener. onTouch () returns false (default), so dispatchTouchEvent () * if in the above source code does not meet, so the onTouchEvent (event) when the Button meets the requirements of CLICKABLE and LONG_CLICKABLE *, true is returned to dispatchTouchEvent (), that is, to continue event distribution. * therefore, you can capture a series of: ACTION_DOWN, ACTION_MOVE, and ACTION_UP. * This explains why the event distribution continues even though onTouch () returns false (default) in the Button !!!!!!!!!!!!! ** 2. Use ImageView for an experiment to analyze dispatchTouchEvent (). * mOnTouchListener. onTouch () returns false (default), so dispatchTouchEvent () * if in the above source code is not satisfied, when onTouchEvent (event) is called) when ImageView does not meet any of CLICKABLE and LONG_CLICKABLE *, false is returned to dispatchTouchEvent (), that is, to terminate event distribution. therefore, only * ACTION_DOWN and no ACTION_MOVE and ACTION_UP * are available for ImageView. This explains why the onTouch () return false (default) in ImageView) event distribution is terminated !!!!!!!!!!!!! ** You can use either of the following methods to distribute a "regular" event like a Button: * 1. Set setOnTouchListener for the ImageView and () returns true instead of false by default. * 2 set android: clickable = "true" for ImageView or OnClickListener for ImageView. * Make the ImageView clickable. * 3 For details, see the example in the following code. * ** reference: * http://blog.csdn.net/guolin_blog/article/details/9097463 * Thank you very much ** code essay: * I have also seen event distribution, but also summed up by myself; can understand not enough. * recently, I plan to refresh the incident with my previous work and Guo Dayun's blog. Distribution. * Due to the differences in understanding, Guo Dayun's blog is difficult for me. Later, I also communicated with him. * So here is my own understanding, which is correct, but it is different from his blog in terms of expression. */public class MainActivity extends Activity {private Button mButton; private ImageView mImageView; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); initButton (); initImageView ();} private void initButton () {mButton = (Button) findViewById (R. id. butto N); mButton. setOnTouchListener (new OnTouchListener () {@ Overridepublic boolean onTouch (View v, MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: System. out. println ("Button ACTION_DOWN"); break; case MotionEvent. ACTION_MOVE: System. out. println ("Button ACTION_MOVE"); break; case MotionEvent. ACTION_UP: System. out. println ("Button ACTION_UP"); break; default: break;} return false ;}}); mBu Tton. setOnClickListener (new OnClickListener () {@ Overridepublic void onClick (View v) {System. out. println ("Button Clicked") ;}}) ;}private void initImageView () {mImageView = (ImageView) findViewById (R. id. imageView); mImageView. setOnTouchListener (new OnTouchListener () {@ Overridepublic boolean onTouch (View v, MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: System. out. println ("Im AgeView ACTION_DOWN "); break; case MotionEvent. ACTION_MOVE: System. out. println ("ImageView ACTION_MOVE"); break; case MotionEvent. ACTION_UP: System. out. println ("ImageView ACTION_UP"); break; default: break;} return false ;}}); // because ImageView is not clickable by default, if the following code is blocked, then, only the ACTION_DOWN of // ImageView does not have ACTION_MOVE and ACTION_UPmImageView.setOnClickListener (new OnClickListener () {@ Overridepublic void onClick (View v) {System. out. Println ("ImageView Clicked") ;}}}/ ** here is the onTouchEvent source code: public boolean onTouchEvent (MotionEvent event) {final int viewFlags = mViewFlags; if (viewFlags & ENABLED_MASK) = DISABLED) {// A disabled view that is clickable still consumes the touch // events, it just doesn't respond to them. return (viewFlags & CLICKABLE) = CLICKABLE | (viewFlags & LONG_CLICKABLE) = LONG_CLICKABLE);} if (m TouchDelegate! = Null) {if (mTouchDelegate. onTouchEvent (event) {return true ;}} if (viewFlags & CLICKABLE) = CLICKABLE | (viewFlags & LONG_CLICKABLE) = LONG_CLICKABLE) {switch (event. getAction () {case MotionEvent. ACTION_UP: boolean prepressed = (mPrivateFlags & PREPRESSED )! = 0; if (mPrivateFlags & PRESSED )! = 0 | prepressed) {// take focus if we don't have it already and we shoshould in // touch mode. boolean focusTaken = false; if (isFocusable () & isFocusableInTouchMode ()&&! IsFocused () {focusTaken = requestFocus ();} if (! MHasPerformedLongPress) {// This is a tap, so remove the longpress check removeLongPressCallback (); // Only perform take click actions if we were in the pressed state if (! FocusTaken) {// Use a Runnable and post this rather than calling // specify mclick directly. this lets other visual state // of the view update before click actions start. if (mPerformClick = null) {mPerformClick = new multiple mclick ();} if (! Post (mPerformClick) {initialize mclick () ;}} if (mUnsetPressedState = null) {mUnsetPressedState = new UnsetPressedState ();} if (prepressed) {mPrivateFlags | = PRESSED; refreshDrawableState (); postDelayed (mUnsetPressedState, ViewConfiguration. getPressedStateDuration ();} else if (! Post (mUnsetPressedState) {// If the post failed, unpress right now mUnsetPressedState. run () ;}removetapcallback () ;}break; case MotionEvent. ACTION_DOWN: if (mPendingCheckForTap = null) {mPendingCheckForTap = new CheckForTap ();} mPrivateFlags | = PREPRESSED; mhas#medlongpress = false; postDelayed (mPendingCheckForTap, ViewConfiguration. getTapTimeout (); break; case MotionEvent. ACTION_CANCE L: mPrivateFlags & = ~ PRESSED; refreshDrawableState (); removeTapCallback (); break; case MotionEvent. ACTION_MOVE: final int x = (int) event. getX (); final int y = (int) event. getY (); // Be lenient about moving outside of buttons int slop = mTouchSlop; if (x <0-slop) | (x> = getWidth () + slop) | (y <0-slop) | (y> = getHeight () + slop) {// Outside button removeTapCallback (); if (mPrivateFlags & PRESSED )! = 0) {// Remove any future long press/tap checks removeLongPressCallback (); // Need to switch from pressed to not pressed mPrivateFlags & = ~ PRESSED; refreshDrawableState () ;}} break;} return true;} return false ;}*/



ButtonSubClass is as follows:

package cc.cv;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.ViewGroup;import android.widget.Button;public class ButtonSubClass extends Button {public ButtonSubClass(Context context) {super(context);// TODO Auto-generated constructor stub}public ButtonSubClass(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public ButtonSubClass(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubreturn super.onTouchEvent(event);}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {// TODO Auto-generated method stubreturn super.dispatchTouchEvent(event);}}

Main. xml is as follows:
<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" >    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_marginTop="100dip"        android:text="Button" />    <ImageView        android:id="@+id/imageView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_marginTop="200dip"        android:src="@drawable/ic_launcher" /></RelativeLayout>



PS:

I have organized event distribution before, but it was too superficial.

Recently I reorganized this part. It was a farewell to this year when it was released at the end of the month.

In fact, the core of this part is the source code Part Of The dispatchTouchEvent () of ViewGroup.

I have not fully understood this part. I look forward to continuing with it in the future.

Learning is a process, which is an embodiment.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.