You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中带@NonNull注解的createFragment方法如何正确返回Fragment消除告警

解决@NonNull注解告警的方案

方法被@NonNull修饰,要求所有分支都必须返回非空的Fragment实例,你当前返回null的逻辑不符合注解约束,才会触发告警。你可以根据业务场景选以下两种兜底方案替换最后的return null:

  • 如果你确定当前适配器只会被那四个城市Activity调用,兜底直接抛出异常即可,出现异常时可以快速发现逻辑问题:
throw new IllegalArgumentException("不支持的Activity类型: " + className);
  • 如果你需要兼容未知场景不崩溃,可以自己实现一个空白占位的EmptyFragment,兜底返回这个Fragment的实例即可。

更优的Fragment返回逻辑实现

你当前的硬编码类名、多层嵌套判断的逻辑扩展性极差,新增城市需要修改大量代码,推荐以下两种优化方案:

方案1:枚举工厂统一管理

把城市对应的Fragment映射关系统一放到枚举里管理,后续新增城市只需要新增枚举项即可,不需要修改核心逻辑:

public enum CityFragmentFactory {
    VANCOUVER(VancouverActivity.class.getSimpleName(), new Class[]{
        VancouverMainFragment.class,
        VancouverAttractionsFragment.class,
        VancouverCoffeeFragment.class,
        VancouverRestaurantFragment.class,
        VancouverActivitiesFragment.class
    }),
    SASKATOON(SaskatoonActivity.class.getSimpleName(), new Class[]{
        SaskatoonMainFragment.class,
        SaskatoonAttractionsFragment.class,
        SaskatoonCoffeeFragment.class,
        SaskatoonRestaurantFragment.class,
        SaskatoonActivitiesFragment.class
    }),
    TORONTO(TorontoActivity.class.getSimpleName(), new Class[]{
        TorontoMainFragment.class,
        TorontoAttractionsFragment.class,
        TorontoCoffeeFragment.class,
        TorontoRestaurantFragment.class,
        TorontoActivitiesFragment.class
    }),
    ST_JOHNS(StJohnsActivity.class.getSimpleName(), new Class[]{
        StJohnsMainFragment.class,
        StJohnsAttractionsFragment.class,
        StJohnsCoffeeFragment.class,
        StJohnsRestaurantFragment.class,
        StJohnsActivitiesFragment.class
    });

    private final String activityClassName;
    private final Class<? extends Fragment>[] fragmentClasses;

    CityFragmentFactory(String activityClassName, Class<? extends Fragment>[] fragmentClasses) {
        this.activityClassName = activityClassName;
        this.fragmentClasses = fragmentClasses;
    }

    public static Fragment create(String activityClassName, int position) {
        for (CityFragmentFactory factory : values()) {
            if (factory.activityClassName.equals(activityClassName)) {
                // 处理position越界
                int safePos = Math.max(0, Math.min(position, factory.fragmentClasses.length - 1));
                try {
                    return factory.fragmentClasses[safePos].newInstance();
                } catch (Exception e) {
                    throw new RuntimeException("Fragment实例化失败", e);
                }
            }
        }
        throw new IllegalArgumentException("不支持的Activity:" + activityClassName);
    }
}

优化后你的原方法可以简化为:

@NonNull
@Override
public Fragment createFragment(int position) {
    String className = mContext.getClass().getSimpleName();
    return CityFragmentFactory.create(className, position);
}

方案2:接口解耦(更推荐)

不要在适配器里判断宿主类型,直接让所有使用该适配器的Activity实现统一的接口,完全解耦适配器和具体Activity的绑定关系:

  1. 首先定义接口
public interface FragmentProvider {
    Fragment getFragmentByPosition(int position);
}
  1. 四个城市Activity都实现该接口,返回对应位置的Fragment实例
  2. 适配器里直接调用接口方法即可
@NonNull
@Override
public Fragment createFragment(int position) {
    if (mContext instanceof FragmentProvider) {
        return ((FragmentProvider) mContext).getFragmentByPosition(position);
    }
    throw new IllegalArgumentException("宿主Activity必须实现FragmentProvider接口");
}

后续新增城市不需要修改适配器任何代码,只需要新Activity实现FragmentProvider接口即可。

内容的提问来源于stack exchange,提问作者DevGoran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 18:27:03