需求:TabHost 包含 A、B、C、More 四個分頁。點擊 A/B/C 正常切換,點擊 More **不切換分頁**,改為彈出選單。
在 OnTabChangedListener 中判斷是否為 More 分頁,若是則立即切回上一個分頁。
public class MainActivity extends TabActivity {
private TabHost tabHost;
private String previousTabTag = "tab_a"; // 預設第一個分頁
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = getTabHost();
// 建立分頁
tabHost.addTab(tabHost.newTabSpec("tab_a").setIndicator("A").setContent(new Intent(this, ActivityA.class)));
tabHost.addTab(tabHost.newTabSpec("tab_b").setIndicator("B").setContent(new Intent(this, ActivityB.class)));
tabHost.addTab(tabHost.newTabSpec("tab_c").setIndicator("C").setContent(new Intent(this, ActivityC.class)));
tabHost.addTab(tabHost.newTabSpec("tab_more").setIndicator("More").setContent(new Intent(this, DummyActivity.class)));
// 設定監聽器
tabHost.setOnTabChangedListener(new TabHost.OnTabChangedListener() {
@Override
public void onTabChanged(String tabId) {
if ("tab_more".equals(tabId)) {
// 1. 彈出選單
showMoreMenu();
// 2. 立即切回上一個分頁(不觸發動畫可用 setCurrentTabByTag)
tabHost.setCurrentTabByTag(previousTabTag);
} else {
// 3. 更新記錄
previousTabTag = tabId;
}
}
});
}
private void showMoreMenu() {
// PopupMenu / AlertDialog / BottomSheetDialog 等
new AlertDialog.Builder(this)
.setTitle("更多功能")
.setItems(new String[]{"設定", "說明", "關於"}, (dialog, which) -> {
// 處理選單項目點擊
})
.show();
}
}
setCurrentTabByTag():直接跳轉指定 Tag 分頁,**不觸發** onTabChanged 遞迴呼叫。previousTabTag:記錄最後一次**成功切換**的分頁,排除 More 分頁。setContent() 可指向空白 DummyActivity,因為永遠不會真正顯示。TabHost / TabActivity **已棄用 (API 13+)**。新專案請使用:
// ViewPager2 + FragmentStateAdapter
ViewPager2 viewPager = findViewById(R.id.viewPager);
viewPager.setAdapter(new TabPagerAdapter(this));
TabLayout tabLayout = findViewById(R.id.tabLayout);
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
tab.setText(titles[position]);
if (position == 3) { // More 分頁
tab.setTabListener(new TabLayout.OnTabSelectedListener() {
@Override public void onTabSelected(TabLayout.Tab tab) {
showMoreMenu();
// 立即取消選中狀態,視覺上不切換
tabLayout.getTabAt(previousPosition).select();
}
@Override public void onTabUnselected(TabLayout.Tab tab) {}
@Override public void onTabReselected(TabLayout.Tab tab) {}
});
}
}).attach();
OnTabChangedListener + setCurrentTabByTag 即時切回。