動態添加 Fragment 時,需為每個 Fragment 設置唯一標識,以便後續查找、替換、移除操作。
| 標識類型 | 設置方式 | 獲取方式 | 適用場景 |
|---|---|---|---|
| ID (int) | XML layout android:id / 容器 View ID | findFragmentById() | 靜態布局、單一 Fragment 容器 |
| Tag (String) | transaction.add(fragment, "tag") | findFragmentByTag() | 動態添加、多 Fragment 同容器 |
| 實例引用 | 應用層集合保存 | 直接訪問 | 複雜狀態管理、跨組件通信 |
// 添加時指定唯一 Tag
String tag = "fragment_" + System.currentTimeMillis(); // 或業務唯一鍵
getSupportFragmentManager().beginTransaction()
.add(R.id.container, fragment, tag)
.commit();
// 後續查找
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
if (fragment != null) {
// 操作 fragment
}
// 替換/移除同理
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, newFragment, newTag)
.commit();
public class FragmentManagerHelper {
private final SparseArray fragments = new SparseArray<>();
private final FragmentManager fm;
public FragmentManagerHelper(FragmentManager fm) { this.fm = fm; }
public void add(int key, Fragment fragment) {
fragments.put(key, fragment);
fm.beginTransaction()
.add(R.id.container, fragment, "key_" + key)
.commit();
}
public Fragment get(int key) {
Fragment f = fragments.get(key);
if (f == null || f.isDetached()) {
// 從 FragmentManager 回收
f = fm.findFragmentByTag("key_" + key);
if (f != null) fragments.put(key, f);
}
return f;
}
public void show(int key) {
FragmentTransaction ft = fm.beginTransaction();
for (int i = 0; i < fragments.size(); i++) {
Fragment f = fragments.valueAt(i);
if (f != null) {
if (fragments.keyAt(i) == key) ft.show(f);
else ft.hide(f);
}
}
ft.commit();
}
}
// 使用
FragmentManagerHelper helper = new FragmentManagerHelper(getSupportFragmentManager());
helper.add(1, new HomeFragment());
helper.add(2, new ProfileFragment());
helper.show(1); // 顯示首頁
// 適用於 Tab 頁面切換,自動管理生命週期、ID、銷毀
ViewPager2 viewPager = findViewById(R.id.viewPager);
viewPager.setAdapter(new FragmentStateAdapter(this) {
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0: return new HomeFragment();
case 1: return new DiscoverFragment();
case 2: return new ProfileFragment();
default: return new Fragment();
}
}
@Override
public int getItemCount() { return 3; }
});
// TabLayout 聯動
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
tab.setText(new String[]{"首頁", "發現", "我的"}[position]);
}).attach();
android:iduser_123、order_456)而非隨機數R.id.xxx,用 Tag 或集合onDestroyView 清理,防洩漏動態 Fragment 標識管理:首選 Tag 機制,簡單標準;固定集合切換用 SparseArray/集合,狀態可控;Tab 頁面用 ViewPager2,框架托管。理解 FragmentManager 的三種查找途徑(ID、Tag、實例),根據業務場景選擇,避免 ID 衝突、引用失效、內存洩漏。