问题描述如下:

我现在有一个TabHost ,装在的页面从左到右依次是Aactivity,Bactivity,Cactivity,Dactivity,Eactivity。  当我指定要跳转到 B, C, D 或者E  Aactivity时候,tabHost总是都会先去加载A页面,这并不是我想要的,我想要的是指定哪个页面就去加载哪个页面。

通过查看源代码发现,我们在tabHost.addTab(spec);的时候,源码如下:

/**

* 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);

}

}

注意查看这段代码

if (mCurrentTab == -1) {

setCurrentTab(0);

}

找到mCurrentTab的定义

protected int mCurrentTab = -1;  默认为-1,所有我们在添加切换卡页面的时候,总是会默认先执行  setCurrentTab(0); 这就是为什么Tabhost总是会先默认加载第一个页面的原因。

找到问题就好办了,我们可以在tabHost.addTab(spec);方法之前,通过反射机制对Tabhost的变量 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();

}

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();

}

原因如下;

当我们执行  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); //设置默认显示界面

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐