問題描述以下: java
我如今有一個TabHost ,裝在的頁面從左到右依次是Aactivity,Bactivity,Cactivity,Dactivity,Eactivity。 當我指定要跳轉到 B, C, D 或者E Aactivity時候,tabHost老是都會先去加載A頁面,這並非我想要的,我想要的是指定哪一個頁面就去加載哪一個頁面。 數組
經過查看源代碼發現,咱們在tabHost.addTab(spec);的時候,源碼以下: this
/** * Add a tab. * @param tabSpec Specifies how to create the indicator and content. */ public void addTab(TabSpec tabSpec) { if (tabSpec.mIndicatorStrategy == null) { throw new IllegalArgumentException("you must specify a way to create the tab indicator."); } if (tabSpec.mContentStrategy == null) { throw new IllegalArgumentException("you must specify a way to create the tab content"); } View tabIndicator = tabSpec.mIndicatorStrategy.createIndicatorView(); tabIndicator.setOnKeyListener(mTabKeyListener); // If this is a custom view, then do not draw the bottom strips for // the tab indicators. if (tabSpec.mIndicatorStrategy instanceof ViewIndicatorStrategy) { mTabWidget.setStripEnabled(false); } mTabWidget.addView(tabIndicator); mTabSpecs.add(tabSpec); if (mCurrentTab == -1) { setCurrentTab(0); } }
注意查看這段代碼 spa
if (mCurrentTab == -1) {
setCurrentTab(0);
} code
找到mCurrentTab的定義 ip
protected int mCurrentTab = -1; 默認爲-1,全部咱們在添加切換卡頁面的時候,老是會默認先執行 setCurrentTab(0); 這就是爲何Tabhost老是會先默認加載第一個頁面的緣由。 ci
找到問題就好辦了,咱們能夠在tabHost.addTab(spec);方法以前,經過反射機制對Tabhost的變量 mCurrentTab進行賦值。 get
Field mCurrentTab = null; try { mCurrentTab = tabHost.getClass() .getDeclaredField("mCurrentTab"); mCurrentTab.setAccessible(true); mCurrentTab.setInt(tabHost, -2); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }
mCurrentTab.setInt(tabHost, -2); 咱們對mCurrentTab進行賦值只要mCurrent的值不等於-1就行。在咱們添加完全部的activity以後。還有一次對mCurrentTab進行賦值操做。不然會報錯 源碼
try { if (mtabIndex == 0) { mCurrentTab.setInt(tabHost, 1); } else { mCurrentTab.setInt(tabHost, 0); } } catch (Exception e){ e.printStackTrace(); }
緣由以下; it
當咱們執行 tabHost.setCurrentTab(mtabIndex); //設置默認顯示界面 查看源碼以下:
public void setCurrentTab(int index) { if (index < 0 || index >= mTabSpecs.size()) { return; } if (index == mCurrentTab) { return; } // notify old tab content if (mCurrentTab != -1) { mTabSpecs.get(mCurrentTab).mContentStrategy.tabClosed(); } mCurrentTab = index; final TabHost.TabSpec spec = mTabSpecs.get(index); // Call the tab widget's focusCurrentTab(), instead of just // selecting the tab. mTabWidget.focusCurrentTab(mCurrentTab); // tab content mCurrentView = spec.mContentStrategy.getContentView(); if (mCurrentView.getParent() == null) { mTabContent .addView( mCurrentView, new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); } if (!mTabWidget.hasFocus()) { // if the tab widget didn't take focus (likely because we're in touch mode) // give the current tab content view a shot mCurrentView.requestFocus(); } //mTabContent.requestFocus(View.FOCUS_FORWARD); invokeOnTabChangeListener(); }
從上面代碼中有2個地方咱們須要注意的是
if (index == mCurrentTab) {
return;
}
注意 傳入的index不能和mCurrentTab值相等,不然直接就return了
// notify old tab content
if (mCurrentTab != -1) {
mTabSpecs.get(mCurrentTab).mContentStrategy.tabClosed();
}
注意紅色部分 mCurrentTab不能小於0 而且不能大於等於mTabSpecs 的size() 不然就會數組越界。
這就是爲何會在最後對mCurrentTab進行從新賦值的緣由
下面是一個連續代碼以下:
Field mCurrentTab = null; try { mCurrentTab = tabHost.getClass() .getDeclaredField("mCurrentTab"); mCurrentTab.setAccessible(true); mCurrentTab.setInt(tabHost, -2); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } // tabActivity實施了跳轉界面 intent = new Intent().setClass(this, AActivity.class); spec = tabHost.newTabSpec("A").setIndicator(disCoverTab).setContent(intent); tabHost.addTab(spec); intent = new Intent().setClass(this, BActivity.class); spec = tabHost.newTabSpec("B").setIndicator(experienceTab).setContent(intent); tabHost.addTab(spec); intent = new Intent().setClass(this, CActivity.class); spec = tabHost.newTabSpec("C").setIndicator(homeTab).setContent(intent); tabHost.addTab(spec); intent = new Intent().setClass(this, DActivity.class); spec = tabHost.newTabSpec("D").setIndicator(tab3).setContent(intent); tabHost.addTab(spec); intent = new Intent().setClass(this, EActivity.class); spec = tabHost.newTabSpec("E").setIndicator(tab5).setContent(intent); tabHost.addTab(spec); try { if (mtabIndex == 0) { mCurrentTab.setInt(tabHost, 1); } else { mCurrentTab.setInt(tabHost, 0); } } catch (Exception e){ e.printStackTrace(); } tabHost.setCurrentTab(mtabIndex); //設置默認顯示界面