Tencent/QMUI_Android · error · RuntimeException

%s 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.

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)

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.