开发者

How to disable all click events of a layout?

I have 开发者_Go百科a layout that contains many views. Is there an easy way to disable all its views click events?


You can pass View for disable all child click event.

public static void enableDisableView(View view, boolean enabled) {
        view.setEnabled(enabled);
        if ( view instanceof ViewGroup ) {
            ViewGroup group = (ViewGroup)view;

            for ( int idx = 0 ; idx < group.getChildCount() ; idx++ ) {
                enableDisableView(group.getChildAt(idx), enabled);
            }
        }
    }


Rather than iterating through all the children view, you can add this function to the parent Layout view

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;
}

This will be called before the onTouchEvent for any child views, and if it returns true, the onTouchEvent for child views wont be called at all. You can create a boolean field member to toggle this state on and off if you want.


I would create a ViewGroup with all the views that you want to enable/disable at the same time and call setClickable(true/false) to enable/disable clicking.


Here is a Kotlin extension function implementation of Parag Chauhan's answer

fun View.setAllEnabled(enabled: Boolean) {
    isEnabled = enabled
    if (this is ViewGroup) children.forEach { child -> child.setAllEnabled(enabled) }
}


You need to call setEnabled(boolean value) method on the view.

view.setClickable(false);
view.setEnabled(false);


If you dont want to set all child views to disable state (because they may look different to enable state) you can use this approach:

private fun toogleTouchable(canTouch: Boolean) {
        container.descendantFocusability =
                if (value) {
                    container.requestFocus()
                    ViewGroup.FOCUS_BLOCK_DESCENDANTS
                } else {
                    ViewGroup.FOCUS_AFTER_DESCENDANTS
                }
    }


my layout has two modes. One preview, when children should not be clickable and the other when children should be clickable. Of all the solutions mentioned here, I found overriding onInterceptTouchEvent most appropriate. Very little code, with no iteration on children.

public boolean onInterceptTouchEvent(MotionEvent ev) {
        if(isPreviewMode())
        {
            //No child is clickable in preview mode.
            return true;
        }

         //All children are clickable otherwise
        return false;
    }

Though disabling children is most popular solution, I am not confortable with that.

You may need to reEnable them and the logic should match exactly. The more is the code, the higher the chances of bugs in the future.


Extension function in Kotlin, with the support of Recycler view.

fun ViewGroup.setEnabledStateForAllChildren(enable: Boolean) {
    children.forEach {
        when (it) {
            is RecyclerView -> {
                it.addOnItemTouchListener(object : SimpleOnItemTouchListener() {
                    override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                        return enable.not()
                    }
                })
            }
            is ViewGroup -> {
                it.setEnabledStateForAllChildren(enable)
            }
            else -> {
                it.isEnabled = enable
            }
        }
    }
}


I would implement onClickListener interface in your activity class and return false in onClick method. I feel it's the easiest way to solve your problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜