Tencent/QMUI_Android · error · RuntimeException
refreshView must be a instance of IRefreshView
Error message
refreshView must be a instance of IRefreshView
What it means
QMUIPullRefreshLayout.addRefreshView throws when the configured mRefreshView is not an instance of IRefreshView. The layout needs the refresh view to implement its refresh interaction contract (onRefreshStart, onRefreshComplete, etc.), so any arbitrary View is rejected.
Source
Thrown at qmui/src/main/java/com/qmuiteam/qmui/widget/pullRefreshLayout/QMUIPullRefreshLayout.java:266
public boolean isRefreshing() {
return mIsRefreshing;
}
/**
* 覆盖该方法以实现自己的 RefreshView。
*
* @return 自定义的 RefreshView, 注意该 View 必须实现 {@link IRefreshView} 接口
*/
protected View createRefreshView() {
return new RefreshView(getContext());
}
private void addRefreshView() {
if (mRefreshView == null) {
mRefreshView = createRefreshView();
}
if (!(mRefreshView instanceof IRefreshView)) {
throw new RuntimeException("refreshView must be a instance of IRefreshView");
}
mIRefreshView = (IRefreshView) mRefreshView;
if (mRefreshView.getLayoutParams() == null) {
mRefreshView.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
addView(mRefreshView);
}
/**
* 设置在下拉过程中 RefreshView 的偏移量
*/
public void setRefreshOffsetCalculator(RefreshOffsetCalculator refreshOffsetCalculator) {
mRefreshOffsetCalculator = refreshOffsetCalculator;
}
@Override
protected int getChildDrawingOrder(int childCount, int i) {View on GitHub (pinned to 026e7d4866)
Solutions
- Make the view passed to setRefreshView implement IRefreshView (and its required methods).
- Use the library's built-in refresh views (e.g. QMUITopDialog-style default or any bundled IRefreshView implementation).
- If wrapping an existing view, implement IRefreshView on the wrapper class you pass to setRefreshView.
Example fix
// before
refreshLayout.setRefreshView(new ProgressBar(context)); // not IRefreshView
// after
class MyRefreshView extends View implements IRefreshView { ... }
refreshLayout.setRefreshView(new MyRefreshView(context)); Defensive patterns
Strategy: type-guard
Validate before calling
View v = candidateRefreshView;
if (v instanceof IRefreshView) {
refreshLayout.setRefreshView(v);
} else {
throw new IllegalArgumentException("refresh view must implement IRefreshView");
} Type guard
private static boolean isIRefreshView(View v) {
return v instanceof IRefreshView;
} Try / catch
try {
refreshLayout.setRefreshView(candidate);
} catch (RuntimeException e) {
Log.e(TAG, "custom refresh view must implement IRefreshView", e);
} Prevention
- Have custom refresh spinners implement IRefreshView (all required methods).
- Prefer the library's built-in IRefreshView implementations.
- Implement the interface on the exact view instance passed to setRefreshView, not a wrapper you don't pass.
When it happens
Trigger: Calling setRefreshView(someView) with a plain View or a custom view that does not implement com.qmuiteam.qmui.widget.pullRefreshLayout.IRefreshView, then triggering layout/refresh initialization.
Common situations: Setting a custom loading spinner View that implements the wrong (or no) refresh interface; migrating from another pull-to-refresh library whose view classes are not adapted; implementing IRefreshView but on a wrapper rather than the set view itself.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- topView must implement from IQMUIContinuousNestedTopView
- bottomView must implement from IQMUIContinuousNestedBottomVi
- delegateView must be a instance of View
- thumbView must be a instance of View
- Not support the type: %s
AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06).
Data as JSON: /api/errors/843061ad3eb9f686.
Report an issue: GitHub.