Android 中 Fragment 的使用指南

Fragment 是 Android 应用开发中的重要组件,它代表 Activity 中的一部分 UI 或行为,可以组合多个 Fragment 在一个 Activity 中构建多窗格 UI,并在不同 Activity 中重复使用某个 Fragment。

基本概念

Fragment 具有自己的生命周期,但依赖于宿主 Activity 的生命周期。每个 Fragment 都有自己的布局和行为。

创建 Fragment

1. 定义 Fragment 类

public class MyFragment extends Fragment {
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // 膨胀 fragment 的布局
        return inflater.inflate(R.layout.fragment_my, container, false);
    }
    
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // 在这里初始化视图和逻辑
    }
}

2. 创建 Fragment 的布局文件 (res/layout/fragment_my.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello Fragment!" />
        
</LinearLayout>

添加 Fragment 到 Activity

方式1: 在 XML 布局中添加 (静态方式,不推荐)

<!-- activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <fragment
        android:id="@+id/myFragment"
        android:name="com.example.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
        
</LinearLayout>

方式2: 在代码中动态添加 (推荐)

public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 检查是否已经添加了Fragment(防止旋转时重复添加)
        if (savedInstanceState == null) {
            // 创建Fragment实例
            MyFragment fragment = new MyFragment();
            
            // 开始Fragment事务
            getSupportFragmentManager().beginTransaction()
                .add(R.id.fragment_container, fragment) // 添加到容器
                .commit();
        }
    }
}

对应的 activity_main.xml 需要有一个容器:

<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Fragment 事务

可以执行添加、移除、替换等操作:

// 替换Fragment
getSupportFragmentManager().beginTransaction()
    .replace(R.id.fragment_container, new AnotherFragment())
    .addToBackStack(null) // 允许用户按返回键返回上一个Fragment
    .commit();

Fragment 生命周期

Fragment 的生命周期方法:

  1. onAttach() - Fragment 与 Activity 关联时调用
  2. onCreate() - Fragment 创建时调用
  3. onCreateView() - 创建 Fragment 的视图层次结构
  4. onActivityCreated() - Activity 的 onCreate() 完成后调用
  5. onStart() - Fragment 可见时调用
  6. onResume() - Fragment 可交互时调用
  7. onPause() - Fragment 不再可交互时调用
  8. onStop() - Fragment 不可见时调用
  9. onDestroyView() - Fragment 的视图被移除时调用
  10. onDestroy() - Fragment 不再使用时调用
  11. onDetach() - Fragment 与 Activity 解除关联时调用

Fragment 与 Activity 通信

1. Fragment 调用 Activity 方法

// 在Fragment中
if (getActivity() instanceof MyActivityInterface) {
    ((MyActivityInterface) getActivity()).doSomething();
}

// Activity实现接口
public interface MyActivityInterface {
    void doSomething();
}

2. Activity 调用 Fragment 方法

MyFragment fragment = (MyFragment) getSupportFragmentManager()
    .findFragmentById(R.id.my_fragment);
if (fragment != null) {
    fragment.doSomethingInFragment();
}

3. 使用 ViewModel 共享数据 (推荐)

// 创建共享ViewModel
public class SharedViewModel extends ViewModel {
    private final MutableLiveData<String> selected = new MutableLiveData<>();
    
    public void select(String item) {
        selected.setValue(item);
    }
    
    public LiveData<String> getSelected() {
        return selected;
    }
}

// 在Activity或Fragment中获取
SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, item -> {
    // 更新UI
});

最佳实践

  1. 使用 androidx.fragment.app 包中的 Fragment(支持库版本)
  2. 避免在 Fragment 中直接持有 Activity 的引用
  3. 使用接口进行 Fragment 与 Activity 的通信
  4. 考虑使用 ViewModel 和 LiveData 进行数据共享
  5. 合理使用 addToBackStack() 管理返回栈
  6. 为 Fragment 添加标签,便于查找:.add(R.id.container, fragment, "TAG")

高级用法

1. Fragment 参数传递

// 创建Fragment时传递参数
public static MyFragment newInstance(String param) {
    MyFragment fragment = new MyFragment();
    Bundle args = new Bundle();
    args.putString("key", param);
    fragment.setArguments(args);
    return fragment;
}

// 在Fragment中获取参数
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        String param = getArguments().getString("key");
    }
}

2. 使用 Navigation 组件管理 Fragment

// 在build.gradle中添加依赖
implementation "androidx.navigation:navigation-fragment:2.3.5"

// 使用NavController导航
NavController navController = Navigation.findNavController(view);
navController.navigate(R.id.action_to_next_fragment);

在 Android 开发中,Fragment 是一个强大的 UI 组件,但并非所有场景都适合使用。以下是 适合不适合 使用 Fragment 的情况对比:


✅ 适合使用 Fragment 的场景

1. 模块化 & 可复用 UI

  • 多个 Activity 共享相同 UI 组件(如底部导航栏、侧滑菜单)
  • 动态替换部分界面(如 ViewPager2 中的页面切换)
  • 不同屏幕尺寸适配(手机/平板不同布局)

2. 复杂 UI 拆分

  • Activity 过于庞大,需要拆分成多个逻辑单元
  • 多个独立视图需要独立生命周期管理
  • TabLayout + ViewPager2(每个 Tab 对应一个 Fragment)

3. 响应式 UI(如横竖屏切换)

  • Fragment 可以单独保存/恢复状态(onSaveInstanceState
  • 比 Activity 更灵活地处理配置变更

4. 导航架构(Navigation Component)

  • 使用 Jetpack Navigation 管理页面跳转
  • 支持 动画过渡深层链接返回栈管理

5. 对话框(DialogFragment)

  • 需要生命周期管理的对话框(如权限请求后的回调)
  • 复用弹窗逻辑(如全屏 DialogFragment)

❌ 不适合使用 Fragment 的场景

1. 超简单 UI

  • 只有一个静态布局(如纯 TextView + Button)
  • 不需要复用或动态调整(直接使用 Activity 或 View 更简单)

2. 性能敏感场景

  • 高频刷新 UI(如游戏主界面)
  • 大量 Fragment 嵌套(影响渲染性能)
  • 低端设备上 Fragment 切换卡顿

3. 临时性 UI

  • Toast、Snackbar、简单 Dialog(不需要生命周期管理)
  • 短暂显示的提示视图(直接使用 View 更高效)

4. 已有成熟架构的 Activity

  • 旧项目 Activity 已经良好组织 UI
  • 第三方库强制使用 Activity(如某些广告 SDK)

5. 需要直接硬件控制

  • 摄像头、传感器等低延迟操作(Fragment 增加间接层)
  • 自定义 SurfaceView/OpenGL 渲染(直接放在 Activity 更合适)

6. 过度嵌套的 Fragment

  • Fragment 里再嵌套多层 Fragment(管理复杂,容易内存泄漏)
  • 推荐改用 View 或 Jetpack Compose 替代

📌 总结:何时用 Fragment?

场景 推荐方案
模块化、可复用 UI ✅ Fragment
复杂 UI 拆分 ✅ Fragment
响应式布局(横竖屏) ✅ Fragment
导航架构(Navigation) ✅ Fragment
简单静态 UI ❌ 直接使用 Activity/View
高性能需求(如游戏) ❌ 避免 Fragment
临时性 UI(Toast/Dialog) ❌ 直接使用 View/Dialog
已有成熟 Activity 架构 ❌ 避免强行引入 Fragment

现代替代方案

  • Jetpack Compose(更灵活的 UI 组件,减少 Fragment 依赖)
  • 自定义 View(适用于高性能或简单 UI)
  • Navigation Component(管理 Fragment 导航更高效)

核心原则

  • 能用 View/Activity 简单解决的,不要强行用 Fragment
  • 需要复用、动态调整、复杂导航的,优先用 Fragment
  • Android 开发中 Fragment 的使用场景

Fragment 是 Android 应用开发中非常重要的组件,它代表了 Activity 中的一部分 UI 或行为。以下是适合使用 Fragment 的典型 UI 场景:

1. 模块化 UI 组件

当 UI 可以被分解为多个独立部分时,适合使用 Fragment:

  • Tab 式界面:每个 Tab 对应一个 Fragment
  • 抽屉导航 (Drawer Navigation):不同导航项对应不同 Fragment
  • 向导式界面:每个步骤作为一个 Fragment
  • 详情/主界面组合:如主列表和详情视图

2. 响应式布局 (Adaptive UI)

多屏幕尺寸适配场景特别适合使用 Fragment:

  • 平板/手机不同布局

    • 平板上并排显示列表和详情 (两个 Fragment)
    • 手机上分开显示 (单独 Fragment)
  • 横竖屏切换

    • 横屏时显示更多内容
    • 竖屏时简化布局

3. 动态 UI 组合

需要运行时动态改变 UI 结构的场景:

  • 条件性显示:根据用户权限显示不同 UI 模块
  • 可配置仪表板:用户可自定义的仪表板界面
  • 可替换内容区域:保持部分 UI 不变,动态切换主要内容

4. 重用 UI 组件

需要在多个 Activity 中重用的 UI 部分:

  • 通用登录面板
  • 产品详情卡片
  • 评论/评分组件
  • 社交媒体分享组件

5. 复杂导航结构

导航架构组件 (Navigation Component) 的核心就是基于 Fragment:

  • 深层链接处理
  • 返回栈管理
  • 过渡动画控制
  • 类型安全参数传递

6. ViewPager 内容页

ViewPager/ViewPager2 的每一页通常都是一个 Fragment:

  • 图片画廊
  • 引导页
  • 可滑动表单
  • 分类内容浏览

不适合使用 Fragment 的情况

  1. 非常简单的 UI:只有一个静态界面的 Activity
  2. 性能敏感场景:Fragment 有额外开销
  3. 需要频繁创建/销毁:考虑使用自定义 View
  4. 与 Activity 生命周期强耦合的逻辑

最佳实践建议

  1. 保持 Fragment 独立:避免直接依赖特定 Activity
  2. 使用 ViewModel 共享数据:而不是直接在 Fragment 间传递
  3. 接口回调:Fragment 通过接口与宿主 Activity 通信
  4. 避免嵌套过深:复杂的 Fragment 嵌套会导致性能问题
  5. 考虑使用 Navigation 组件:简化 Fragment 管理和导航

Fragment 的设计初衷是提供更灵活的 UI 组合方式,随着 Android 发展,它已成为构建现代化、响应式 Android 应用的核心组件之一。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐