Tencent/QMUI_Android · error · RuntimeException

Action view already exists other parent view.

Error message

Action view already exists other parent view.

What it means

QMUIPullLayout.setActionView(PullActionBuilder) throws when the builder's action view is already attached to a different parent. Like setTargetView, the layout only accepts detached views or its own children as action views.

Source

Thrown at qmui/src/main/java/com/qmuiteam/qmui/widget/pullLayout/QMUIPullLayout.java:237

    public void setActionView(View view, LayoutParams lp) {
        PullActionBuilder builder = new PullActionBuilder(view, lp.edge)
                .canOverPull(lp.canOverPull)
                .pullRate(lp.pullRate)
                .needReceiveFlingFromTargetView(lp.needReceiveFlingFromTarget)
                .receivedFlingFraction(lp.receivedFlingFraction)
                .scrollSpeedPerPixel(lp.scrollSpeedPerPixel)
                .targetTriggerOffset(lp.targetTriggerOffset)
                .triggerUntilScrollToTriggerOffset(lp.triggerUntilScrollToTriggerOffset)
                .scrollToTriggerOffsetAfterTouchUp(lp.scrollToTriggerOffsetAfterTouchUp)
                .actionInitOffset(lp.actionInitOffset);
        view.setLayoutParams(lp);
        setActionView(builder);
    }

    public void setActionView(@NonNull PullActionBuilder builder) {
        if (builder.mActionView.getParent() != this) {
            throw new RuntimeException("Action view already exists other parent view.");
        }
        if (builder.mActionView.getParent() == null) {
            ViewGroup.LayoutParams lp = builder.mActionView.getLayoutParams();
            if (lp == null) {
                lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            }
            addView(builder.mActionView, lp);
        }
        if (builder.mPullEdge == PULL_EDGE_LEFT) {
            mLeftPullAction = builder.build();
        } else if (builder.mPullEdge == PULL_EDGE_TOP) {
            mTopPullAction = builder.build();
        } else if (builder.mPullEdge == PULL_EDGE_RIGHT) {
            mRightPullAction = builder.build();
        } else if (builder.mPullEdge == PULL_EDGE_BOTTOM) {
            mBottomPullAction = builder.build();
        }
    }

View on GitHub (pinned to 026e7d4866)

Solutions

  1. Detach the action view from its current parent (parent.removeView(view)) before setActionView.
  2. Create a new action view / builder instance per pull layout or per edge.
  3. If it must be attached to this layout already, only reuse views that are direct children of this QMUIPullLayout.

Example fix

// before
pullLayout.setActionView(sameBuilder); // action view used by another layout
// after
PullActionBuilder builder = new PullActionBuilder(actionView);
pullLayout.setActionView(builder); // freshly created, unattached action view
Defensive patterns

Strategy: type-guard

Validate before calling

Object parent = builder.mActionView.getParent();
if (parent == null || parent == pullLayout) {
    pullLayout.setActionView(builder);
}

Type guard

private static boolean canSetAction(QMUIPullLayout layout, PullActionBuilder b) {
    return b.mActionView.getParent() == null || b.mActionView.getParent() == layout;
}

Try / catch

try {
    pullLayout.setActionView(builder);
} catch (RuntimeException e) {
    ViewGroup old = (ViewGroup) builder.mActionView.getParent();
    if (old != null) old.removeView(builder.mActionView);
    pullLayout.setActionView(builder);
}

Prevention

When it happens

Trigger: Calling pullLayout.setActionView(builder) where builder.mActionView still has a non-null parent other than this pull layout — e.g. a view inflated and attached elsewhere, or reused from another pull layout/edge.

Common situations: Reusing the same action view (or builder) for multiple pull layouts or multiple edges; creating the action view and attaching it to a temporary container before passing it in.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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