Android: Fragment 的使用指南
Override// 膨胀 fragment 的布局@Override// 在这里初始化视图和逻辑。
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 的生命周期方法:
onAttach()
- Fragment 与 Activity 关联时调用onCreate()
- Fragment 创建时调用onCreateView()
- 创建 Fragment 的视图层次结构onActivityCreated()
- Activity 的 onCreate() 完成后调用onStart()
- Fragment 可见时调用onResume()
- Fragment 可交互时调用onPause()
- Fragment 不再可交互时调用onStop()
- Fragment 不可见时调用onDestroyView()
- Fragment 的视图被移除时调用onDestroy()
- Fragment 不再使用时调用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
});
最佳实践
- 使用
androidx.fragment.app
包中的 Fragment(支持库版本) - 避免在 Fragment 中直接持有 Activity 的引用
- 使用接口进行 Fragment 与 Activity 的通信
- 考虑使用 ViewModel 和 LiveData 进行数据共享
- 合理使用
addToBackStack()
管理返回栈 - 为 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 导航更高效)
核心原则:
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 的情况
- 非常简单的 UI:只有一个静态界面的 Activity
- 性能敏感场景:Fragment 有额外开销
- 需要频繁创建/销毁:考虑使用自定义 View
- 与 Activity 生命周期强耦合的逻辑
最佳实践建议
- 保持 Fragment 独立:避免直接依赖特定 Activity
- 使用 ViewModel 共享数据:而不是直接在 Fragment 间传递
- 接口回调:Fragment 通过接口与宿主 Activity 通信
- 避免嵌套过深:复杂的 Fragment 嵌套会导致性能问题
- 考虑使用 Navigation 组件:简化 Fragment 管理和导航
Fragment 的设计初衷是提供更灵活的 UI 组合方式,随着 Android 发展,它已成为构建现代化、响应式 Android 应用的核心组件之一。
更多推荐
所有评论(0)