{"record":{"id":"2aeeafb6837743aa","repo":"Tencent/QMUI_Android","slug":"topview-must-implement-from-iqmuicontinuousnestedt","errorCode":null,"errorMessage":"topView must implement from IQMUIContinuousNestedTopView","messagePattern":"topView must implement from IQMUIContinuousNestedTopView","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedScrollLayout.java","lineNumber":189,"sourceCode":"            mOnScrollListeners.add(onScrollListener);\n        }\n    }\n\n    public void removeOnScrollListener(OnScrollListener onScrollListener) {\n        mOnScrollListeners.remove(onScrollListener);\n    }\n\n    public void setKeepBottomAreaStableWhenCheckLayout(boolean keepBottomAreaStableWhenCheckLayout) {\n        mKeepBottomAreaStableWhenCheckLayout = keepBottomAreaStableWhenCheckLayout;\n    }\n\n    public boolean isKeepBottomAreaStableWhenCheckLayout() {\n        return mKeepBottomAreaStableWhenCheckLayout;\n    }\n\n    public void setTopAreaView(View topView, @Nullable LayoutParams layoutParams) {\n        if (!(topView instanceof IQMUIContinuousNestedTopView)) {\n            throw new IllegalStateException(\"topView must implement from IQMUIContinuousNestedTopView\");\n        }\n        if (mTopView != null) {\n            removeView(((View) mTopView));\n        }\n        mTopView = (IQMUIContinuousNestedTopView) topView;\n        mTopView.injectScrollNotifier(new IQMUIContinuousNestedScrollCommon.OnScrollNotifier() {\n            @Override\n            public void notify(int innerOffset, int innerRange) {\n                int offsetCurrent = mTopAreaBehavior == null ? 0 : -mTopAreaBehavior.getTopAndBottomOffset();\n                int bottomCurrent = mBottomView == null ? 0 : mBottomView.getCurrentScroll();\n                int bottomRange = mBottomView == null ? 0 : mBottomView.getScrollOffsetRange();\n                dispatchScroll(innerOffset, innerRange, offsetCurrent, getOffsetRange(), bottomCurrent, bottomRange);\n            }\n\n            @Override\n            public void onScrollStateChange(View view, int newScrollState) {\n                // not need this. top view scroll is driven by top behavior\n            }","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/Tencent/QMUI_Android/blob/026e7d486677d6593a96689cd590ec3561176717/qmui/src/main/java/com/qmuiteam/qmui/nestedScroll/QMUIContinuousNestedScrollLayout.java#L171-L207","documentation":"QMUIContinuousNestedScrollLayout.setTopAreaView() requires the view passed as the top area to implement the IQMUIContinuousNestedTopView interface, which provides scroll coordination callbacks (injectScrollNotifier, etc.). If the view does not implement it, the layout cannot drive its nested scrolling, so it throws an IllegalStateException immediately instead of failing later at runtime.","triggerScenarios":"Calling setTopAreaView(view, layoutParams) with a plain View, ViewGroup, RecyclerView without implementing IQMUIContinuousNestedTopView, or a custom view that forgot the interface.","commonSituations":"Developers replacing the default QMUIContinuousNestedTopScrollLayout/WebView with a custom header view, or copying sample code that passes a raw layout, hit this on first layout inflation.","solutions":["Make the view's class implement IQMUIContinuousNestedTopView (implement getScrollHeight, getCurrentScroll, scrollBy, consumeScroll, injectScrollNotifier etc.).","Alternatively use QMUI's built-in implementations such as QMUIContinuousNestedTopScrollLayout, QMUIContinuousNestedTopRecyclerView or QMUIContinuousNestedTopWebView as the top view.","If a custom view cannot implement the interface, wrap it inside a class that implements IQMUIContinuousNestedTopView and delegates scrolling to it.","Check you are not passing the wrong view (e.g. bottom view) to setTopAreaView."],"exampleFix":"// before\nlayout.setTopAreaView(new LinearLayout(context), null);\n\n// after\nclass MyTopView extends LinearLayout implements IQMUIContinuousNestedTopView {\n    // implement injectScrollNotifier, consumeScroll, getScrollHeight, getCurrentScroll ...\n}\nlayout.setTopAreaView(new MyTopView(context), null);","handlingStrategy":"type-guard","validationCode":"if (!(topView instanceof IQMUIContinuousNestedTopView)) {\n    throw new IllegalArgumentException(\"topView must implement IQMUIContinuousNestedTopView\");\n}\nlayout.setTopAreaView(topView, null);","typeGuard":"boolean isTopAreaViewValid(View v) {\n    return v instanceof IQMUIContinuousNestedTopView;\n}","tryCatchPattern":"try {\n    layout.setTopAreaView(topView, layoutParams);\n} catch (IllegalStateException e) {\n    Log.e(TAG, \"topView invalid, falling back to default\", e);\n    layout.setTopAreaView(new QMUIContinuousNestedTopScrollLayout(context), layoutParams);\n}","preventionTips":["Always implement IQMUIContinuousNestedTopView on custom header views","Prefer QMUI's built-in top view implementations","Write an assert/unit test on the view class before wiring the nested scroll layout"],"tags":["android","qmui","nested-scroll","type-mismatch","interface-not-implemented"],"backgroundTag":"type-mismatch","analyzedSha":"026e7d486677d6593a96689cd590ec3561176717","analyzedAt":"2026-09-06T13:32:24.816Z","contentChangedAt":"2026-09-06T13:32:24.816Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}