Tencent/QMUI_Android · error · RuntimeException

did not call through to super.shouldPreventSwipeBack()

Error message

%s did not call through to super.shouldPreventSwipeBack()

What it means

QMUIFragment's swipe-back mechanism calls canHandleSwipeBack(), which sets an internal mCalled flag when the base shouldPreventSwipeBack() is invoked. If a subclass overrides shouldPreventSwipeBack() without calling super, mCalled stays false while canHandle is true, so the library throws to enforce the override contract.

Solutions

  1. Call super.shouldPreventSwipeBack() first in the override and use its result
  2. Return DRAG_DIRECTION_NONE / base value combined with your custom logic
  3. Remove the override entirely if default behavior is acceptable

Example fix

// before
@Override
protected int shouldPreventSwipeBack() {
    return mCustomCondition ? DRAG_DIRECTION_NONE : DRAG_DIRECTION_LEFT;
}
// after
@Override
protected int shouldPreventSwipeBack() {
    int base = super.shouldPreventSwipeBack();
    return mCustomCondition ? DRAG_DIRECTION_NONE : base;
}
Defensive patterns

Strategy: type-guard

Prevention

When it happens

Trigger: Overriding shouldPreventSwipeBack() in a subclass without calling super.shouldPreventSwipeBack(), then attempting a swipe-back gesture on a fragment where canHandleSwipeBack() is true.

Common situations: Customizing swipe-back direction logic and forgetting the super call; copy-pasted overrides from older library versions that did not require super.

Related errors


AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06). Data as JSON: /api/errors/ab1e3d3d070ddd8a. Report an issue: GitHub.

Appendix: source

Thrown at arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java:591

            mCacheRootView = rootView;
        } else {
            if (rootView.getParent() != null) {
                ((ViewGroup) rootView.getParent()).removeView(rootView);
            }
        }
        SwipeBackLayout swipeBackLayout = SwipeBackLayout.wrap(rootView,
                dragViewMoveAction(),
                new SwipeBackLayout.Callback() {
                    @Override
                    public int getDragDirection(SwipeBackLayout swipeBackLayout, SwipeBackLayout.ViewMoveAction viewMoveAction, float downX, float downY, float dx, float dy, float touchSlop) {

                        mCalled = false;
                        if(mDisableSwipeBackByMutiStarted){
                            return DRAG_DIRECTION_NONE;
                        }
                        boolean canHandle = canHandleSwipeBack();
                        if (canHandle && !mCalled) {
                            throw new RuntimeException(getClass().getSimpleName() + " did not call through to super.shouldPreventSwipeBack()");
                        }

                        if(!canHandle){
                            return DRAG_DIRECTION_NONE;
                        }
                        return QMUIFragment.this.getDragDirection(
                                swipeBackLayout, viewMoveAction, downX, downY, dx, dy, touchSlop);
                    }

                    @Override
                    public void reportFrequentlyRequestLayout(int count, long duration) {
                        QMUIFragment.this.reportFrequentlyRequestLayout(count, duration);
                    }
                });
        initSwipeBackLayout(swipeBackLayout);
        if(getParentFragment() != null){
            mCacheSwipeBackView = swipeBackLayout;
        }

View on GitHub (pinned to 026e7d4866)