Handle unexpected interception of fragment sliding events

Source: Internet
Author: User

See the content of load_data_waiting_layout.xml, RelativeLayout, ProgressBar, TextView, and other controls. After clickable is set to true, the ProgramListFragment sliding event is no longer supported. If you do not set the clickable attribute or set it to false, the ProgramListFragment sliding event is supported.

programListFragment.getView().setOnTouchListener(programTouchListener);

Is the onTouch method of programListFragment. getView () not executed after the clickable attribute is set to true?

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/layout_waiting"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:clickable="true"    android:background="#00ffff" >    <ProgressBar        android:id="@+id/waiting"        style="?android:attr/progressBarStyleLarge"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:clickable="true"        android:background="#ff00ff" />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/waiting"        android:layout_centerHorizontal="true"        android:layout_marginTop="10dp"        android:text="@string/loading_data"        android:textSize="22sp"        android:clickable="true"        android:background="#0000ff" /></RelativeLayout>

Setting the clickable attribute in an xml file is equivalent to calling the setClickable method in a program. Use the setClickable method of android. view. View to analyze the impact of the clickable attribute on the touch event.

Void setClickable (boolean clickable)

public void setClickable(boolean clickable) {    setFlags(clickable ? CLICKABLE : 0, CLICKABLE);}

Void setFlags (int flags, int mask)

/** * Set flags controlling behavior of this view. * * @param flags Constant indicating the value which should be set * @param mask Constant indicating the bit range that should be changed */void setFlags(int flags, int mask) {    int old = mViewFlags;    mViewFlags = (mViewFlags & ~mask) | (flags & mask);    int changed = mViewFlags ^ old;    if (changed == 0) {        return;    }    int privateFlags = mPrivateFlags;    /* Check if the FOCUSABLE bit has changed */    if (((changed & FOCUSABLE_MASK) != 0) &&            ((privateFlags & PFLAG_HAS_BOUNDS) !=0)) {        if (((old & FOCUSABLE_MASK) == FOCUSABLE)                && ((privateFlags & PFLAG_FOCUSED) != 0)) {            /* Give up focus if we are no longer focusable */            clearFocus();        } else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)                && ((privateFlags & PFLAG_FOCUSED) == 0)) {            /*             * Tell the view system that we are now available to take focus             * if no one else already has it.             */            if (mParent != null) mParent.focusableViewAvailable(this);        }        if (AccessibilityManager.getInstance(mContext).isEnabled()) {            notifyAccessibilityStateChanged();        }    }    if ((flags & VISIBILITY_MASK) == VISIBLE) {        if ((changed & VISIBILITY_MASK) != 0) {            /*             * If this view is becoming visible, invalidate it in case it changed while             * it was not visible. Marking it drawn ensures that the invalidation will             * go through.             */            mPrivateFlags |= PFLAG_DRAWN;            invalidate(true);            needGlobalAttributesUpdate(true);            // a view becoming visible is worth notifying the parent            // about in case nothing has focus.  even if this specific view            // isn't focusable, it may contain something that is, so let            // the root view try to give this focus if nothing else does.            if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {                mParent.focusableViewAvailable(this);            }        }    }    /* Check if the GONE bit has changed */    if ((changed & GONE) != 0) {        needGlobalAttributesUpdate(false);        requestLayout();        if (((mViewFlags & VISIBILITY_MASK) == GONE)) {            if (hasFocus()) clearFocus();            clearAccessibilityFocus();            destroyDrawingCache();            if (mParent instanceof View) {                // GONE views noop invalidation, so invalidate the parent                ((View) mParent).invalidate(true);            }            // Mark the view drawn to ensure that it gets invalidated properly the next            // time it is visible and gets invalidated            mPrivateFlags |= PFLAG_DRAWN;        }        if (mAttachInfo != null) {            mAttachInfo.mViewVisibilityChanged = true;        }    }    /* Check if the VISIBLE bit has changed */    if ((changed & INVISIBLE) != 0) {        needGlobalAttributesUpdate(false);        /*         * If this view is becoming invisible, set the DRAWN flag so that         * the next invalidate() will not be skipped.         */        mPrivateFlags |= PFLAG_DRAWN;        if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE) && hasFocus()) {            // root view becoming invisible shouldn't clear focus and accessibility focus            if (getRootView() != this) {                clearFocus();                clearAccessibilityFocus();            }        }        if (mAttachInfo != null) {            mAttachInfo.mViewVisibilityChanged = true;        }    }    if ((changed & VISIBILITY_MASK) != 0) {        if (mParent instanceof ViewGroup) {            ((ViewGroup) mParent).onChildVisibilityChanged(this,                    (changed & VISIBILITY_MASK), (flags & VISIBILITY_MASK));            ((View) mParent).invalidate(true);        } else if (mParent != null) {            mParent.invalidateChild(this, null);        }        dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK));    }    if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {        destroyDrawingCache();    }    if ((changed & DRAWING_CACHE_ENABLED) != 0) {        destroyDrawingCache();        mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;        invalidateParentCaches();    }    if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {        destroyDrawingCache();        mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;    }    if ((changed & DRAW_MASK) != 0) {        if ((mViewFlags & WILL_NOT_DRAW) != 0) {            if (mBackground != null) {                mPrivateFlags &= ~PFLAG_SKIP_DRAW;                mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;            } else {                mPrivateFlags |= PFLAG_SKIP_DRAW;            }        } else {            mPrivateFlags &= ~PFLAG_SKIP_DRAW;        }        requestLayout();        invalidate(true);    }    if ((changed & KEEP_SCREEN_ON) != 0) {        if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {            mParent.recomputeViewAttributes(this);        }    }    if (AccessibilityManager.getInstance(mContext).isEnabled()            && ((changed & FOCUSABLE) != 0 || (changed & CLICKABLE) != 0                    || (changed & LONG_CLICKABLE) != 0 || (changed & ENABLED) != 0)) {        notifyAccessibilityStateChanged();    }}

Extended TextView, override onTouchEvent method, and return false.

public class MyTextView extends TextView {    public MyTextView(Context context) {        super(context);    }    public MyTextView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyTextView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        super.onTouchEvent(event);        return false;    }}

Debugging result: if false is returned, the TextView parameter is invalid.


Trace touch event execution

11-08 15:22:57.524: D/MyLinearLayout(22210): ++onInterceptTouchEvent++11-08 15:22:57.524: D/MyLinearLayout(22210): result:false11-08 15:22:57.524: D/MyRelativeLayout(22210): ++onInterceptTouchEvent++11-08 15:22:57.524: D/MyRelativeLayout(22210): result:false11-08 15:22:57.524: D/MyLinearLayout(22210): ++onInterceptTouchEvent++11-08 15:22:57.534: D/MyLinearLayout(22210): result:false11-08 15:22:57.534: D/MyTextView(22210): ++onTouchEvent++11-08 15:22:57.534: D/MyTextView(22210): result:true

The above log shows that MyText is in the ViewTree level 4th, level 1, 2, and level 3 are MyLinearLayout, MyRelativeLayout, and MyLinearLayout. when a touch event occurs, the onInterceptTouchEvent method of level 1, 2, and 3 is called for processing. If onInterceptTouchEvent returns false, the onTouchEvent of the lower-level View or the onInterceptTouchEvent of the lower-level ViewGoup will be called for processing.


11-08 15:52:56.374: D/MyLinearLayout(23972): ++onInterceptTouchEvent++11-08 15:52:56.374: D/MyLinearLayout(23972): result:false11-08 15:52:56.374: D/MyRelativeLayout(23972): ++onInterceptTouchEvent++11-08 15:52:56.374: D/MyRelativeLayout(23972): result:false11-08 15:52:56.374: D/MyLinearLayout(23972): ++onInterceptTouchEvent++11-08 15:52:56.374: D/MyLinearLayout(23972): result:false11-08 15:52:56.374: D/MyTextView(23972): ++onTouchEvent++11-08 15:52:56.374: D/MyTextView(23972): result:true11-08 15:52:56.374: D/MyTextView(23972): ++dispatchTouchEvent++11-08 15:52:56.374: D/MyTextView(23972): result:true11-08 15:52:56.374: D/MyLinearLayout(23972): ++dispatchTouchEvent++11-08 15:52:56.374: D/MyLinearLayout(23972): result:true11-08 15:52:56.374: D/MyRelativeLayout(23972): ++dispatchTouchEvent++11-08 15:52:56.374: D/MyRelativeLayout(23972): result:true11-08 15:52:56.374: D/MyLinearLayout(23972): ++dispatchTouchEvent++11-08 15:52:56.374: D/MyLinearLayout(23972): result:true

The preceding log shows that the onInterceptTouchEvent method of level 1, 2, and 3 and the onTouchEvent method of level 4th are called sequentially. Then, the dispatchTouchEvent method of Level 4, 3, and 2 is called sequentially.


Call toString () to identify the current View

11-08 16:08:38.424: D/WatchTvFragment(25580): programListFragment.getView():android.support.v4.app.NoSaveStateFrameLayout{421799f0 V.E..... ........ 427,0-986,703 #7f070077 app:id/program_list_fragment}11-08 16:09:18.994: D/MyLinearLayout(25580): ++onInterceptTouchEvent++11-08 16:09:18.994: D/MyLinearLayout(25580): com.tvie.ivideo.pad.live.MyLinearLayout{42188478 V.E..... ........ 0,0-559,703}11-08 16:09:18.994: D/MyLinearLayout(25580): result:false11-08 16:09:18.994: D/MyRelativeLayout(25580): ++onInterceptTouchEvent++11-08 16:09:18.994: D/MyRelativeLayout(25580): com.tvie.ivideo.pad.live.MyRelativeLayout{4216cfd0 V.E..... ........ 0,0-559,43}11-08 16:09:18.994: D/MyRelativeLayout(25580): result:false11-08 16:09:18.994: D/MyLinearLayout(25580): ++onInterceptTouchEvent++11-08 16:09:18.994: D/MyLinearLayout(25580): com.tvie.ivideo.pad.live.MyLinearLayout{4216d1f8 V.E..... ........ 0,0-524,43}11-08 16:09:18.994: D/MyLinearLayout(25580): result:false11-08 16:09:18.994: D/MyTextView(25580): ++onTouchEvent++11-08 16:09:18.994: D/MyTextView(25580): com.tvie.ivideo.pad.live.MyTextView{4216e750 V.ED..C. ...P.... 321,7-412,36 #7f07014b app:id/tomorrow}11-08 16:09:18.994: D/MyTextView(25580): result:true11-08 16:09:18.994: D/MyTextView(25580): ++dispatchTouchEvent++11-08 16:09:18.994: D/MyTextView(25580): com.tvie.ivideo.pad.live.MyTextView{4216e750 V.ED..C. ...P.... 321,7-412,36 #7f07014b app:id/tomorrow}11-08 16:09:18.994: D/MyTextView(25580): result:true11-08 16:09:18.994: D/MyLinearLayout(25580): ++dispatchTouchEvent++11-08 16:09:18.994: D/MyLinearLayout(25580): com.tvie.ivideo.pad.live.MyLinearLayout{4216d1f8 V.E..... ........ 0,0-524,43}11-08 16:09:18.994: D/MyLinearLayout(25580): result:true11-08 16:09:18.994: D/MyRelativeLayout(25580): ++dispatchTouchEvent++11-08 16:09:18.994: D/MyRelativeLayout(25580): com.tvie.ivideo.pad.live.MyRelativeLayout{4216cfd0 V.E..... ........ 0,0-559,43}11-08 16:09:18.994: D/MyRelativeLayout(25580): result:true11-08 16:09:18.994: D/MyLinearLayout(25580): ++dispatchTouchEvent++11-08 16:09:18.994: D/MyLinearLayout(25580): com.tvie.ivideo.pad.live.MyLinearLayout{42188478 V.E..... ........ 0,0-559,703}11-08 16:09:18.994: D/MyLinearLayout(25580): result:true

The above log shows:

The root layout of programListFragment. getView () and R. layout. watchtv_program_list is not the same view.


11-08 17:02:35.134: D/MyLinearLayout(25580): ++onInterceptTouchEvent++11-08 17:02:35.134: D/MyLinearLayout(25580): result:false11-08 17:02:35.134: D/MyRelativeLayout(25580): ++onInterceptTouchEvent++11-08 17:02:35.134: D/MyRelativeLayout(25580): result:false11-08 17:02:35.134: D/MyLinearLayout(25580): ++onInterceptTouchEvent++11-08 17:02:35.134: D/MyLinearLayout(25580): result:false11-08 17:02:35.134: D/MyLinearLayout(25580): ++onTouchEvent++11-08 17:02:35.134: D/MyLinearLayout(25580): result:false11-08 17:02:35.134: D/MyLinearLayout(25580): ++dispatchTouchEvent++11-08 17:02:35.134: D/MyLinearLayout(25580): result:false11-08 17:02:35.134: D/MyRelativeLayout(25580): ++onTouchEvent++11-08 17:02:35.134: D/MyRelativeLayout(25580): result:false11-08 17:02:35.134: D/MyRelativeLayout(25580): ++dispatchTouchEvent++11-08 17:02:35.134: D/MyRelativeLayout(25580): result:false11-08 17:02:35.134: D/MyLinearLayout(25580): ++onTouchEvent++11-08 17:02:35.134: D/MyLinearLayout(25580): result:false11-08 17:02:35.134: D/MyLinearLayout(25580): ++dispatchTouchEvent++11-08 17:02:35.134: D/MyLinearLayout(25580): result:false11-08 17:02:35.134: D/WatchTvFragment(25580): ++programTouchListener.onTouch++


When the touch event occurs in MyLinearLayout outside MyTextView, the fragment can slide left and right. View logs: MyLinearLayout outside MyTextView returns false in the dispatchTouchEvent method. Previously, MyTextView returned true in the dispatchTouchEvent method, so that all the xxxLayout statements returned true.

If the returned value is false in the MyLinearLayout. dispatchTouchEvent method, the click Event of the lower-level MyTextView is invalid. It indicates that the return value of dispatchTouchEvent plays an important role.


11-08 17:27:55.144: D/MyLinearLayout(32017): ++onInterceptTouchEvent++11-08 17:27:55.144: D/MyLinearLayout(32017): result:false11-08 17:27:55.144: D/MyRelativeLayout(32017): ++onInterceptTouchEvent++11-08 17:27:55.144: D/MyRelativeLayout(32017): result:false11-08 17:27:55.144: D/MyLinearLayout(32017): ++onInterceptTouchEvent++11-08 17:27:55.144: D/MyLinearLayout(32017): result:false11-08 17:27:55.144: D/MyTextView(32017): ++onTouchEvent++11-08 17:27:55.144: D/MyTextView(32017): result:true11-08 17:27:55.144: D/MyTextView(32017): ++dispatchTouchEvent++11-08 17:27:55.144: D/MyTextView(32017): result:false11-08 17:27:55.154: D/MyLinearLayout(32017): ++onTouchEvent++11-08 17:27:55.154: D/MyLinearLayout(32017): result:false11-08 17:27:55.154: D/MyLinearLayout(32017): ++dispatchTouchEvent++11-08 17:27:55.154: D/MyLinearLayout(32017): result:false11-08 17:27:55.154: D/MyRelativeLayout(32017): ++onTouchEvent++11-08 17:27:55.154: D/MyRelativeLayout(32017): result:false11-08 17:27:55.154: D/MyRelativeLayout(32017): ++dispatchTouchEvent++11-08 17:27:55.154: D/MyRelativeLayout(32017): result:false11-08 17:27:55.154: D/MyLinearLayout(32017): ++onTouchEvent++11-08 17:27:55.154: D/MyLinearLayout(32017): result:false11-08 17:27:55.154: D/MyLinearLayout(32017): ++dispatchTouchEvent++11-08 17:27:55.154: D/MyLinearLayout(32017): result:false11-08 17:27:55.154: D/WatchTvFragment(32017): ++programTouchListener.onTouch++

Row 8th: The dispatchTouchEvent method of MyTextView of level 4th returns false. Next, call the onTouchEvent and dispatchTouchEvent methods at level 3, 2, and 1. In the preceding log, the dispatchTouchEvent method returns true, and the onTouchEvent method will not be called.

Void android. view. View. setOnClickListener (OnClickListener l)

Register a callback to be invoked when this view is clicked. If this view is not clickable, it becomes clickable.

Parameters:

LThe callback that will run

public void setOnClickListener(OnClickListener l) {    if (!isClickable()) {        setClickable(true);    }    getListenerInfo().mOnClickListener = l;}

When setOnClickListener is called, if clickable is set to false, it is set to true.

Reference link:

1. http://www.aslibra.com/blog/post/android_GestureDetector.php

2. http://blog.csdn.net/lyb2518/article/details/7889169


Related Article

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.