scwang90/SmartRefreshLayout · error · RuntimeException

DefaultRefreshFooterCreator can not return null

Error message

DefaultRefreshFooterCreator can not return null

What it means

The footer counterpart of the header error: in onAttachedToWindow(), when no footer was configured (mRefreshFooter == null) and a global default footer creator is registered via SmartRefreshLayout.setDefaultRefreshFooterCreator(...), that creator returned null and the library throws immediately. The creator must return a non-null RefreshFooter; returning null violates the API contract.

Source

Thrown at refresh-layout-kernel/src/main/java/com/scwang/smart/refresh/layout/SmartRefreshLayout.java:422

        // 在非编辑模式下,如果 onFinishInflate 初始化组件未成功,onAttachedToWindow 可以进行补充处理
        if (!thisView.isInEditMode()) {

            if (mRefreshHeader == null) {
                if (sHeaderCreator != null) {
                    RefreshHeader header = sHeaderCreator.createRefreshHeader(thisView.getContext(), this);
                    //noinspection ConstantConditions
                    if (header == null) {
                        throw new RuntimeException("DefaultRefreshHeaderCreator can not return null");
                    }
                    setRefreshHeader(header);
                }
            }
            if (mRefreshFooter == null) {
                if (sFooterCreator != null) {
                    RefreshFooter footer = sFooterCreator.createRefreshFooter(thisView.getContext(), this);
                    //noinspection ConstantConditions
                    if (footer == null) {
                        throw new RuntimeException("DefaultRefreshFooterCreator can not return null");
                    }
                    setRefreshFooter(footer);
                }
            } else {
                mEnableLoadMore = mEnableLoadMore || !mManualLoadMore;
            }

            if (mRefreshContent == null) {
                for (int i = 0, len = getChildCount(); i < len; i++) {
                    View view = getChildAt(i);
                    if ((mRefreshHeader == null || view != mRefreshHeader.getView()) &&
                            (mRefreshFooter == null || view != mRefreshFooter.getView())) {
                        mRefreshContent = new RefreshContentWrapper(view);
                    }
                }
            }
            if (mRefreshContent == null) {
                final int padding = SmartUtil.dp2px(20);

View on GitHub (pinned to 224db48f8a)

Solutions

  1. If the intent was to disable load-more, call refreshLayout.setEnableLoadMore(false) instead of returning null from the creator.
  2. Otherwise make the creator always return a non-null footer, e.g. (context, layout) -> new ClassicsFooter(context).
  3. If no global default footer is wanted, remove the setDefaultRefreshFooterCreator registration entirely.
  4. Audit all return branches of a conditional creator and add a guaranteed non-null fallback.

Example fix

// before (crashes on attach)
SmartRefreshLayout.setDefaultRefreshFooterCreator((context, layout) -> null); // tried to disable load-more

// after
refreshLayout.setEnableLoadMore(false); // correct way to disable load-more
// or, if you want a default footer:
SmartRefreshLayout.setDefaultRefreshFooterCreator((context, layout) -> new ClassicsFooter(context));
Defensive patterns

Strategy: validation

Validate before calling

// Probe the creator once before registering so null returns surface immediately
DefaultRefreshFooterCreator creator = (context, layout) -> buildFooter(context);
if (creator.createRefreshFooter(context, null) == null) {
    throw new IllegalStateException("Footer creator must never return null");
}
SmartRefreshLayout.setDefaultRefreshFooterCreator(creator);

Prevention

When it happens

Trigger: Registering sFooterCreator with setDefaultRefreshFooterCreator((context, layout) -> null), or a lambda whose conditional branches can fall through to a null return, then attaching any SmartRefreshLayout without an xml/code-set footer. Fires only on the footer path — header path is handled by the sibling check above it.

Common situations: Disabling load-more by returning null from the footer creator (wrong approach — use setEnableLoadMore(false) instead); unfinished creator stubs during prototyping; branch logic where one theme returns a footer and another returns null; version upgrades where a footer class moved packages and the old import resolves to something uninstantiable.

Related errors


AI-assisted analysis of scwang90/SmartRefreshLayout@224db48f8a (2026-08-14). Data as JSON: /api/errors/00879acc1a8b35b8. Report an issue: GitHub.