make a foreground view click-through

rupps picture rupps · May 16, 2013 · Viewed 7.6k times · Source

I don't find the way to make this work.

My application has 2 FrameLayouts with many child views (suppose ImageViews for simplicity), stacked one over the other.

My problem is, I need the FrameLayout on TOP and ALL ITS CHILDREN to let touches pass through them, reaching the underlying FrameLayout (and its children). Something like pointer-events:none in HTML applied to all imageviews of the TOP framelayout.

I've tried setClickable(false) and setEnabled(false) both on the FrameLayout and its children, but if I click a disabled children (for example an ImageView), the touch will not reach an underlying ImageView (that is child of the bottom FrameLayout)

The following code is my best attempt to disable a FrameLayout and its children (mSlideLayout is the parent FrameLayout, layer is each imageview children). Am I missing something??

/** Create the layers structure into the layout */
void create_layers() {
    Context context=getActivity();
    mSlideLayout.removeAllViews();
    for (FunqLayer layer:mLayers) {
        if (layer!=null) {
            View v=layer.init_internal(context, mSlideLayout); // constructs the child layer, suppose it's an ImageView
            if ((v!=null) && (mIsMuteTouches)) {
                v.setEnabled(false);
                v.setClickable(false);
                // this should obviously let touches pass through but it doesnt :(
            }
        }
    }
    if (mIsMuteTouches) {
        // also do the same in the FrameLayout itself with no luck :(
        mSlideLayout.setEnabled(false);
        mSlideLayout.setClickable(false);
    }
} 

Answer

rupps picture rupps · May 16, 2013

Yes, obviouly I was missing onInterceptTouchEvent , overriding this in the framelayout and returning true makes the above routine redundant:

    FrameLayout slideLayout=new FrameLayout(getActivity()){
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            if (mIsMuteTouches) return true;
            return super.onInterceptTouchEvent(ev);
        }
    };