Search code examples
androidfragmentfocus

Disable focus on fragment


I'm working on application for TV platform and use RCU for navigation.

I have use case where I have two fragments one above each other and visible on the screen at the same time.

Is there a way to disable focusing fragment that is below? setFocusable(false) on fragments view doesnt work, and I'm able to focus elements in fragment below.

Thanks in advance.


Solution

  • The solution that I've come up with in the end is:

    Added custom Lifecycle listeners for the fragment namely: onFragmentResume and onFragmentPause events which I call manually when I need to show/hide or switch between fragments.

    @Override
    public void onFragmentResume() {
    
        //Enable focus
        if (getView() != null) {
    
            //Enable focus
            setEnableView((ViewGroup) view, true);
    
            //Clear focusable elements
            focusableViews.clear();
        }
    
        //Restore previous focus
        if (previousFocus != null) {
            previousFocus.requestFocus();
        }
    }
    
    @Override
    public void onFragmentPause() {
    
        //Disable focus and store previously focused
        if (getView() != null) {
    
            //Store last focused element
            previousFocus = getView().findFocus();
    
            //Clear current focus
            getView().clearFocus();
    
            //Disable focus
            setEnableView((ViewGroup) view, false);
        }
    }
    
    /**
     * Find focusable elements in view hierarchy
     *
     * @param viewGroup view
     */
    private void findFocusableViews(ViewGroup viewGroup) {
    
        int childCount = viewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = viewGroup.getChildAt(i);
            if (view.isFocusable()) {
                if (!focusableViews.contains(view)) {
                    focusableViews.add(view);
                }
            }
            if (view instanceof ViewGroup) {
                findFocusableViews((ViewGroup) view);
            }
        }
    }
    
    /**
     * Enable view
     *
     * @param viewGroup
     * @param isEnabled
     */
    private void setEnableView(ViewGroup viewGroup, boolean isEnabled) {
    
        //Find focusable elements
        findFocusableViews(viewGroup);
    
        for (View view : focusableViews) {
            view.setEnabled(isEnabled);
            view.setFocusable(isEnabled);
        }
    }