首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android TabHost + Fragment 實現父頁嵌套子頁切換且子頁邏輯可執行

     編輯:程式設計綜合問答

方案選型

現代 Android 推薦 ViewPager2 + FragmentStateAdapter + TabLayout,而非過時的 TabHost。但若維護舊項目必須用 TabHost,核心在於:

  • TabHost 的 TabContentFactory 返回 Fragment 容器(FrameLayout)。
  • 使用 FragmentTransaction 替換容器內 Fragment,而非靜態寫死所有子頁佈局。

TabHost + Fragment 關鍵代碼骨架

public class MainActivity extends FragmentActivity {
    private TabHost tabHost;
    private FragmentManager fm;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        tabHost = findViewById(android.R.id.tabhost);
        tabHost.setup();
        fm = getSupportFragmentManager();
        
        addTab("Tab1", R.id.container1, Fragment1.class);
        addTab("Tab2", R.id.container2, Fragment2.class);
        // ...
    }
    
    private void addTab(String tag, int containerId, Class clz) {
        TabHost.TabSpec spec = tabHost.newTabSpec(tag).setIndicator(tag);
        spec.setContent(new TabHost.TabContentFactory() {
            @Override
            public View createTabContent(String tag) {
                FrameLayout fl = new FrameLayout(MainActivity.this);
                fl.setId(containerId);
                return fl;
            }
        });
        tabHost.addTab(spec);
        
        // 監聽切換,動態替換 Fragment
        tabHost.setOnTabChangedListener(tabTag -> {
            FragmentTransaction ft = fm.beginTransaction();
            // 隱藏所有、顯示目標(或 replace)
            ft.replace(containerId, Fragment.instantiate(this, clz.getName()));
            ft.commit();
        });
        
        // 首次手動觸發第一個
        if (tabHost.getCurrentTab() == 0) tabHost.setCurrentTab(0);
    }
}

現代化遷移建議

// build.gradle
implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation "com.google.android.material:material:1.9.0"

// 布局



// Activity
viewPager.setAdapter(new FragmentStateAdapter(this) {
    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragments[position]; // 預創建或懶加載
    }
    @Override
    public int getItemCount() { return fragments.length; }
});
new TabLayoutMediator(tabLayout, viewPager, (tab, pos) -> tab.setText(titles[pos])).attach();

優勢

  • Fragment 生命週期自動管理(setMaxLifecycle)。
  • 預加載、滑動平滑、RTL 支援。
  • 無需手動處理 FragmentTransaction,減少 Bug。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved